SQL Server - Updates ¿recursivos?

 
Vista:

Updates ¿recursivos?

Publicado por Luis (2 intervenciones) el 30/09/2008 21:13:15
He estado mirando vuestro foro y lo cierto es que me gustaría participar en él. De momento me gustaría haceros una pregunta que me tiene loco desde hace muchísimo tiempo. A ver si me logro explicar.

Estoy haciendo un programa en el que se realizan unos arrastres de saldos. Hasta ahí todo normal. Pero el problema me surge cuando se produce la siguiente situación:

Tengo una tabla de unos 120.000 registros.

El registro número 1.000, por ejemplo, cambia su valor. En lugar de ser una salida de 12 euros, fue de 24 euros.

A partir de esta modificación, todos los registros desde el 1000 hasta el fin deben cambiar sus movimientos en base a esa modificación. Es decir, que si antes (por ejemplo) el registro daba un precio medio de 1,20 euros y ahora es de 1,22, pues el resto deben cambiar a 1,22. Esto, con un UPDATE se soluciona sin problemas. El caso está en que la modificación de un registros podría generar que ese UPDATE masivo ya no lo sea y que el programa, o en este caso el SQL, deba tener en cuenta las modificaciones que el propio UPDATE está generando.

Esto lo soluciono o bien con un cursor o bien haciendo obras de ingeniería, con tablas auxiliares, etc. Pero origina una pérdida de tiempo, recursos y redimiento muy grande cuando las modificaciones son de miles de registros.

¿Existe algún comando SQL o algún truco o algún algo para que según se ejecute el UPDATE de una fila, el UPDATE de la siguiente tenga en cuenta el cambio de la anterior? ¿Es decir, que "arrastre" los movimientos?

Muchísimas gracias de antemamo. Ya he visto que gente como Isaías están muy puestos en estos temas y, sinceramente, me salvaríais la vida.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Updates ¿recursivos?

Publicado por Isaias (3308 intervenciones) el 30/09/2008 23:02:52
¿Existe integridad en tu tabla?, esto es, los registros se apuntan asi mismos mediante un FK y un PK

No me gusta mucho la metodologia de ir guardando el SALDO en una columna o campo, ¿porque?, por el problema que mencionas, es mucho mejor hacer el calculo del saldo en caliente, al momento de hacer el query o bien, llevar campos calculados.

Pero necesitaria mas informacion en cuanto al diseño de tu tabla.

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Updates ¿recursivos?

Publicado por Luis (2 intervenciones) el 01/10/2008 00:43:38
Te comento.

La tabla lleva, entre otros muchos campos, los siguientes:

ARTÍCULO
FECHA
CONTADOR
UNIDADES DEL REGISTRO
IMPORTE DEL REGISTRO
SALDO ACUMULADO
SALDO IMPORTE ACUMULADO.

Estoy totalmente de acuerdo contigo en que no soy partidario de llevar los saldos guardados en un campo. Pero resulta que en este programa se tienen que poder consultar los saldos a tiempo real y a cualquier fecha muy a menudo. Así que la tabla, que ahora contiene más de 2,5 millones de registros, se vuelve loca para sumar esos movimientos de un artículo determinado a una fecha determinada. Para evitar esto añadí los campos de acumulados. De esta forma no tengo más que llamar al valor más alto del campo CONTADOR (que se va renumerando dependiendo de las fecha real del dato y la que introduce el usuario), en esa fecha determinada y para ese artículo determinado y lo tengo prácticamente en el acto.

Por todas las pruebas que he hecho, cuando ejecuto una instrucción para efectuar ese cálculo tarda bastante más y, lógicamente, en cuanto más crece la base de datos más tarda. No sé si a este primer problema me puedes aportar alguna sugerencia.

Ahora voy con el tema de la consulta. Imagina los siguientes registros:

1.- Fecha 01/01/2000 - Unidades 120 (entradas) - Precio 1200 euros - Precio medio actual 10 euros

2.- Fecha 05/01/2000 - Unidades -20 (salidas) - Precio (al medio anterior) 200 euros - Saldo actual 1000 euros - uds actuales 100 - Medio actual - 10 euros.

3.- (Abrevio más) Entradas de 1000 unidades a 7 euros con lo que quedan 1100 unidades con un valor de 8000 euros a 7,2727 euros unidad

4.- Salidas de 500 unidades a 7,2727 euros unidad con lo que quedan 600 unidades con un valor de 4.363,63 euros a 7,2727 euros unidad.

En el supuesto caso de que la entrada número 1 fuera errónea y en lugar de realizarse la entrada a 10 euros se hubiera tenido que hacer a 15, el valor de salidas del movimiento 2 es distinto y el del 4 también. Y, además, no proporcional a esa modificación del movimiento 1 ya que existe otra entrada en el movimiento 3 que hace que varíe el precio medio.

Con esto pretendo dotar al programa de retroactividad. Si el programa no tiene esta utilidad (que no la tienen la mayoría de programas del mercado), los márgenes de la venta (o consumos de producción) de los movimientos de salidas serían falsos. Los precios medios variarían a partir del último movimiento y, como diría un conformista, "bueno... comido por servido". Pero a mí no me gusta eso. Quiero la información exacta.

Y de ahí todo este lío. ¿Como se puede variar el precio medio (y como consecuencia el de salida) de esos movimientos? Si lo hago con un UPDATE en bloque no lo hace correcto ya que la modificación del movimiento de salidas número 2 afecta al saldo restante y, por lo tanto, debe tenerse en cuenta para determinar el precio medio de los restantes. El UPDATE lo hace todo en bloque, con lo que no me sirve.

Si hubiera algún UPDATE que "recordara o acumulara" los valores que va actualizando y que no fuera por un cursor, serían fantástico. O si hubiera algún método de cálculo que sacara esta información de estos millones de registros en tiempos decentes, pues también.

Me he extendido, amigo Isaías, pero creo que es la mejor forma de hacerme enteder y de que me puedas echar una mano.

Por otra parte no sé que es eso de que los registros se apuntan a sí mismos mediante un FK o un PK. Supongo que te refieres a tablas relacionales, pero no lo sé. Y si es eso, pues no. Lo único que utilizo en mi base de datos son los índices.

Muchas gracias y perdona el rollo.
Luis
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Updates ¿recursivos?

Publicado por Isaias (3308 intervenciones) el 01/10/2008 17:47:58
Probemos una consulta, ¿te parece?, verifica que tengas los indices adecuados y antes de ejecutar tu consulta, setea

SET STATISTICS IO ON

Para analizar las lecturas que esta haciendo.

select
a.id,
a.entrada,
a.salida,
(
select sum(b.entrada - b.salida)
from dbo.t1 as b
where b.id <= a.id
) as saldo
from dbo.t1 as a
order by a.id

Te explico, aunque es un calculo de EXISTENCIA en un inventario, debe funcionar para calcular el saldo de una cuenta, ID es el identificador, entrada (sum), salida (resta), que en tu caso son ABONOS y CARGOS.

En este otro ejemplo, se hacel el calculo TOTAL_AMOUNT, sobre cuentas contables

SELECT YourTable.Co_ID,
YourTable.Cu_ID,
YourTable.Doc_ID,
YourTable.Doc_Date,
YourTable.Doc_Amount,
DerivedTable.Total_Amount
FROM YourTable
INNER JOIN (SELECT Co_ID,
Cu_ID, SUM(Doc_Amount) AS Total_Amount
FROM YourTable GROUP BY Co_ID, Cu_ID) AS DerivedTable ON YourTable.Co_ID = DerivedTable.Co_ID
AND YourTable.Cu_ID = DerivedTable.Cu_ID WHERE YourTable.Doc_Type = 1

Dime si te funciona o si puedes adaptarlo a tus necesidades
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar