FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
||||
|
||||
Problema interesante
Hola amigos,
Estoy trabajando en un pequeño sistema de Facturacion y Ctrl. de Stock con una BD tipo Access a traves de ADO. La mayoria de las consultas son realizadas mediante TADODataSet con cursosres y locks del tipo BatchUpdates (una especie de Cache del Cliente). Basicamente, cada vez que el Punto de Venta en la linea de Caja mite un comprobante de venta, se descuenta el stock disponible del producto vendido mediante una instruccion SQL del tipo UPDATE a traves de un TADOCommand. Finalizado el proceso se llama al metodo ADODataSet1.BatchUpdate; vinculado a la tabla Productos y el Stock es actualizado. Hasta aqui todo bien. Un ejemplo, tenemos 10 productos vendemos 1, nos queda 9. La cuestion es que, si en el Puinto de Venta, el usuario elimina uno de los items ingresados, la operación "devuelve" la cantidad al stock con otra instruccion UPDATE, en el ejemplo, tenemos 9, devolvemos 1, nos vuelve a quedar 10. Lamentablemenete al momenteo de lanzar la instrucción ADODataSet1.BatchUpdate; como respuesta obtengo 11. Esto es, si emito el comprobante toma el primer UPDATE y deja el stock en 9, pero si hago un cambio solo toma el ultimo UPDATE por lo que en este caso adicion la cantidad sin realizar el descuento anterior. Que puede ser?. Como decimos en Argentina, sera cosa e'Mandinga?
__________________
Gracias de antemano por vuestra ayuda. ·.:*:.·Yako·.:*:.· |
#2
|
||||
|
||||
La cosa es simple: O lo haces en linea o en batch. No se puede mezclar.
O haces las actualizaciones directo cada vez el usuario haga algo (dentro de una transaccion obvio) o lo haces en los dataset y al finalizar ejecuta todas las acciones. El ultimo caso obvio requiere calcular tomando en cuenta tanto el contenido local como el remoto, pero el punto es que ambas cosas al tiempo no se pueden...
__________________
El malabarista. |
#3
|
||||
|
||||
Cita:
Justamente, como trabajo con BATCHUPDATE todas las operaciones se hacen off-line de la BD. Lo que intuyo es que con ADO en este metodo, el comando UPDATE "registrado" es el ultimo enviado y no todos los que se emitan. Como información adicional, todos los dataset estan cargados y desvinculados de sus conexiones. Te hago un ejemplo de forma muy escueta de lo que tengo: Código:
//--------------------- //cCod y nStock son variables globales cargadas en distintas situaciones. //--------------------- Procedure Vender; begin cCOD:= ADODataSetPRODUCTOS.FiledByName('Codigo').AsString; //Var global nStock:= ADODataSetPRODUCTOS.FiledByName('Cantidad').AsInteger; //Var global ADODataSetDETALLEFACTURA.Insert; ADODataSetDETALLEFACTURA.FiledByName('Codigo').AsString:= cCOD; ADODataSetDETALLEFACTURA.FiledByName('Cantidad').AsInteger:= nCantPedida; ADODataSetDETALLEFACTURA.Post; ADOCommand1.Commantext:='UPDATE Productos SET Cantidad= :Param1 WHERE Codigo=:Param2;'; ADOCommand1.Parametres[0]:= (nStock - nCantPedida); ADOCommand1.Parametres[1]:= cCod; ADOCommand1.Execute; end; Procedure Borrar: begin //nStock viene con la cantidad actual resultante en Productos. MiCOD:= ADODataSetDETALLEFACTURA.FiledByName('Codigo').AsString; MiCant:= ADODataSetDETALLEFACTURA.FiledByName('Cantidad').AsInteger; ADODataSetDETALLEFACTURA.Delete; ADOCommand1.Commantext:='UPDATE Productos SET Cantidad= :Param1 WHERE Codigo=:Param2;'; ADOCommand1.Parametres[0]:= (nStock + MiCant); ADOCommand1.Parametres[1]:= MiCod; ADOCommand1.Execute; end; ================ Procedure Registrar; begin ADOConnection.ConnectionString:= MiConexion; ADODataSetPRODUCTOS.ConnectionString:= ADOCOnnection; ADODataSetPRODUCTOS.Active:= True; ADODataSetDETALLEFACTURA.ConnectionString:= ADOCOnnection; ADODataSetDETALLEFACTURA.Active:= True; ADOCommand1.BeginTrans; TRY ADODataSetProductos.UpdateBatch; ADODataSetDETALLEFACTURA.UpdateBatch; ADOCommand1.CommitTrans; EXCEPT ADOCommand1.RollBackTrans; END; ADOConnection.Active:= False; end;
__________________
Gracias de antemano por vuestra ayuda. ·.:*:.·Yako·.:*:.· |
#4
|
||||
|
||||
Precisamente, lo que tiene ADOCommand1 se ejecuta en linea pero lo que tiene ADODataSet... queda almacenado en memoria. Estas mezclando dos cosas al tiempo. Lo que deberias hacer (para una operacion en batch) tener la tabla de productos en un dataset tambien en batch y recalcular alli....
SIN EMBARGO eso te causaria problemas de concurrencia (porque los demas usuarios tendrian su propia copia) y me imagino por eso lo haces como esta. Lo que te toca hacer es: 1- Usar un trigger en las tablas que afectan estos datos... 2- Usar un sistema de calculadora en memoria, donde almacenas todos los calculos, osea tener una lista asi: ListaOperaciones Codigo Cantidad 1 2 1 -1 3 -1 2 3 y al finalizar el usuario ejecutar TODAS las acciones almacenadas. De hecho, eso es tener un log de transacciones. Asi es como se puede hacer de forma fiable en un ambiente de batch sin perjudicarse por las acciones de los demas usuarios...
__________________
El malabarista. |
#5
|
||||
|
||||
Aaa..... ahora entiendo. El ADOCommand funciona independientemente del Batch.
Evidentemente voy a tener que llevar un control de los movimiento de cantidades en variables de memoria hasta que llegue el momento de actualizar. ¿Alguna idea o sugerencia al respecto?
__________________
Gracias de antemano por vuestra ayuda. ·.:*:.·Yako·.:*:.· |
|
|
|