Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Tablas planas
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 10-06-2005
Avatar de hgiacobone
hgiacobone hgiacobone is offline
Miembro
 
Registrado: may 2003
Ubicación: La Plata, Bs. As., Argentina
Posts: 165
Poder: 22
hgiacobone Va por buen camino
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·.:*:.·
Responder Con Cita
  #2  
Antiguo 10-06-2005
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.913
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
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.
Responder Con Cita
  #3  
Antiguo 10-06-2005
Avatar de hgiacobone
hgiacobone hgiacobone is offline
Miembro
 
Registrado: may 2003
Ubicación: La Plata, Bs. As., Argentina
Posts: 165
Poder: 22
hgiacobone Va por buen camino
Cita:
Empezado por mamcx
La cosa es simple: O lo haces en linea o en batch. No se puede mezclar.
Gracias por la info.
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·.:*:.·
Responder Con Cita
  #4  
Antiguo 10-06-2005
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.913
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
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.
Responder Con Cita
  #5  
Antiguo 10-06-2005
Avatar de hgiacobone
hgiacobone hgiacobone is offline
Miembro
 
Registrado: may 2003
Ubicación: La Plata, Bs. As., Argentina
Posts: 165
Poder: 22
hgiacobone Va por buen camino
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·.:*:.·
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 04:31:49.


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
Copyright 1996-2007 Club Delphi