Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Control de stock (https://www.clubdelphi.com/foros/showthread.php?t=89708)

toni.vi 31-01-2016 19:22:49

Jack
Entiendo tu problema, y no se porque no te funciona, a mi me funciona correctamente. Te paso mi codigo para que lo revises respecto al tuyo.
Solo añadir que tambien debes crear un trigger para beforeinsert

Código SQL [-]

CREATE TRIGGER FGEHIMAR_BU0 FOR FARTICULO
ACTIVE BEFORE INSERT OR UPDATE POSITION 1
AS
begin
  /* Trigger text */
  update FARTICULO
  set FARTICULO.STOCK = coalesce(FARTICULO.STOCK,0) - old.cantidad
  where FARTICULO.articulo  = old.Articulo;

end
^

CREATE TRIGGER FGEHIMAR_AU0 FOR FARTICULO
ACTIVE AFTER UPDATE POSITION 0
AS
begin
  /* Trigger text */

  update FARTICULO
  set FARTICULO.STOCK = coalesce(FARTICULO.STOCK,0) + new.cantidad
  where FARTICULO.articulo  = new.Articulo;

end
^

Jack 01-02-2016 10:21:29

Gracias por contestar
 
Gracias a todos por contestar, ( yo prefiero sin sarcasmos ), pero lo que me explicaís no es lo que pregunto. Ya veo que como Lepe dice el stock se queda a cero, pero antes de la modificación habían 10 unidades old.unidades, luego de la modificación hay 15 new.unidades, de donde sacas que ahora el stock se queda = 0. Digo que habra +10 -15 = -5. Si pongo 10 y quito 10 entonces si estoy igual. No pegunto si la secuencia de sumas y restas esta bien.
Mi pregunta es si el update de la tabla stocks puede fallar al grabar la linea de venta e ir a actualizar el stock en los triggers after insert, before update, after delete de la linea de ventas. Esa es mi pregunta, la secuencia lógica del programa no me falla, lo he probado con muchos casos y calcula bien el stock ( al borrar, al modificar y al añadir lineas nuevas, lo hace bien, suma y resta cuando toca ).
El desajuste ocurre cuando hay muchos movimientos o cuando hay varios usuarios trabajando o por algún motivo que yo no logro comprender.
Bien es cierto que utilizo un dbgrid, haciendo un commitretaining inmediatamente despues del post. Si esto no funciona que alguien me explique 2 cosas. a: para que esta el dbgrid, b: para que esta el commitretaining.
También es cierto que leí hace años en alguna página que se desaconsejaba el uso del commitretaining, aunque como he dicho antes en las pruebas que realicé en mi ordenador parecía que funcionaba bien.
Otra cosa a la que no puedo renunciar es a que el stock se actualice siempre a cada linea de venta, no al final de la introducción de cada documento, repito, necesito que sea al insertar una nueva linea o al actualizar una linea ya insertada con anterioridad.
Estuve hace tiempo tentado de utilizar un stringgrid para trabajar, pero no lo ví operativo y la estética que le pude dar no fue nada de mi agrado.

Despues de todo lo dicho, repito la pregunta.
Tengo una tabla linventas LV., dos campos LV.articulo, LV.unidades. Inserto una linea nueva LV.Articulo = 'A1', LV.Unidades = 25. La tabla LinVentas tiene un trigger after insert, donde hago lo siguiente a una tabla Stocks. ( esta asegurado que en esta tabla existe un articulo A1 )
Código SQL [-]
update Stocks ST, 
     set ST.UnidadesVentas = ST.UnidadesVentas + New.Unidades
 where ST.Articulo = New.Articulo
En la tabla stocks queda ST.Articulo = 'A1', ST.TotalUnidades = 25.
Utilizo la misma lógica con
los trigger after delete, before update, after update de la tabla linventas.
Esto se puede hacer o hay algún motivo por el que no se deba hacer este sistema de actualización de stocks. ( Las transaciones de las lineas finalizan con un commitretaining.
Podría ser que hubiera una situación de introducciones de lineas de ventas de varios usuarios concurrentes ( +10).

Yo solo preguntaba esto, me disculpo si no lo pregunte bien o si dije algo no conveniente al leer vuestras contestaciones. Cuando he preguntado algo siempre me habeís contestado amablemente y yo lo he agradecido siempre. Esto del stock me tiene muy preocupado. Actualmente he reprogramado todo el sistema y ya no lo hago de esta manera, aunque aún lo estoy probando, pero si que utilizo este sistema para otros menesteres. Es por eso que insisto tanto en la pregunta.
Gracias de antemano.

mamcx 01-02-2016 21:25:45

Cita:

Empezado por Jack (Mensaje 501746)
Mi pregunta es si el update de la tabla stocks puede fallar al grabar la linea de venta e ir a actualizar el stock en los triggers after insert, before update, after delete de la linea de ventas. Esa es mi pregunta, la secuencia lógica del programa no me falla, lo he probado con muchos casos y calcula bien el stock ( al borrar, al modificar y al añadir lineas nuevas, lo hace bien, suma y resta cuando toca ).
El desajuste ocurre cuando hay muchos movimientos o cuando hay varios usuarios trabajando o por algún motivo que yo no logro comprender.

Ok, ya esto es otra cosa.

Puede fallar? Si.

Pero para eso son las transacciones. Existen diversos niveles de transaccion, con diversas garantias y promesas.

Puedes (y deberias) leer los docs al respecto:

http://www.firebirdsql.org/manual/is...nsactions.html

-------

Un problema con la forma como casi siempre se hace esto es que el proceso es *destructivo*, y una vez completo, es prácticamente imposible reconstruir lo que paso.

Sin embargo, existe una forma de diseño que garantiza la reproducibilidad y el rastreo preciso de lo que pasa, y es muy similar a como funciona la contabilidad (Contabilidad bien echa NUNCA hace ediciones o borrados, solo inserta pa' delante):

http://www.codeproject.com/Articles/...Event-sourcing

En resumen, debes guardar un log de cada pasa que se ejecuta, y hacer un replay para reconstuir el valor actual. Eso es lo que hace una BD con su log de transacciones.

En el modelo comun, tienes:

UPDATE Producto=1 Cant = 2 WHRE Id=1

Cuando esto termina, no sabes que paso antes. El proceso es *destructivo*

En cambio, si lo vuelves un log:

Inv ID=1 ADD Producto=1 Cant = 1
Inv ID=1 UPDATE Producto=1 Cant = 2
Inv ID=1 ADD Producto=2 Cant = 3
Inv ID=1 DELETE

Como vez, al hacer esto asi, tenes un log inmutable que puedes evaluar y saber exactamente que paso, en que orden, etc. Es la forma segura de darle la maxima integridad y fiabilidad (y tiene otros beneficios, pero dejemoslo asi por ahora).

Tambien, considero que es la forma correcta de implementar un inventario.

P.D: Para la velocidad de consultas, puedes tener una tabla auxiliar que mantiene el valor actual desde los triggers del log. Es *mas* trabajo, pero es la forma de tener una auditoria perfecta y fiable.

TiammatMX 17-05-2017 18:48:45

Cita:

Empezado por Jack (Mensaje 501721)
...esta sera la última vez que entre en esta página, jamás volveré a pisar los pies por aqui.
Es triste encontrase con gente así por la vida, aunque tengo claro que siempre que tenga que medirme con gente de este tipo, yo estaré infinitamente por encima de ellos, por respeto a los demas y por educación.

No hace falta el que se va ni sobra el que se queda...


La franja horaria es GMT +2. Ahora son las 01:47:44.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi