Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 02-11-2005
Carlos Hurtado Carlos Hurtado is offline
Miembro
 
Registrado: dic 2004
Posts: 30
Poder: 0
Carlos Hurtado Va por buen camino
Manejo de errores en Master Detail

Hola Amigos nuevemente estoy recurriendo a ustedes para que me ayuden a solucionar este problema:
Tengo Firebird 1.5 con Delphi 7
IbTransaction1. Params
read_commited
rec_version
nowait

La Tabla Detalle (ValesDetalle) proviene de un stringgrid y la Tabla Maestro(ValesMaestro) proviene de datos de cliente mas la suma del campo Total de ValesDetalle.

En las inserciones de la Tabla Maestro y la Tabla Detalle no tengo problemas, ellos estan cuando tengo que actualizar la Tabla StockMaestro del campo Cantidad de la Tabla Detalle.
Para esto lo hago con una Stored Procedure que debe manejar las stes. situaciones:
Si no hay stock debe hacer un rollback
Si hay un lock_conflict deberia repetir la procedure hasta hacer el update
Si hay cualquier otro error debe hacer un rollback.

La Procedure


CREATE PROCEDURE ACTUALIZA_VALESDETALLE(
VID_VALE VARCHAR(12),
VID_PRODUCTO VARCHAR(12),
VCANTIDAD DECIMAL(7,2),
VDESCRIPCION VARCHAR(40),
VVALORUNITARIO NUMERIC,
VTOTAL NUMERIC)
RETURNS (
FLAG SMALLINT)
AS
DECLARE VARIABLE V_STOCK DECIMAL(7,2);
BEGIN
INSERT INTO VALESDETALLE
(
ID_VALE,
ID_PRODUCTO,
CANTIDAD,
DESCRIPCION,
VALORUNITARIO,
TOTAL
)
VALUES
(
:VID_VALE,
:VID_PRODUCTO,
:VCANTIDAD,
:VDESCRIPCION,
:VVALORUNITARIO,
:VTOTAL
);
SELECT EXISTENCIA FROM STOCKMAESTRO WHERE ID_PRODUCTO = :VID_PRODUCTO
INTO :V_STOCK;
IF (:V_STOCK >= :VCANTIDAD) THEN
BEGIN
UPDATE STOCKMAESTRO
SET EXISTENCIA = :V_STOCK - :VCANTIDAD
WHERE ID_PRODUCTO = :VID_PRODUCTO;
FLAG = 0;
END
ELSE
EXCEPTION NO_STOCKDETALLE;
WHEN EXCEPTION NO_STOCKDETALLE DO
BEGIN
FLAG = 1;
END
WHEN GDSCODE lock_conflict DO
BEGIN
¡¡¡¡NO SE QUE HACER!!!
END
WHEN ANY DO
BEGIN
FLAG = 1;
END
END ^



Y el procedimiento en Delphi
///////
For a := 1 to stringGrid1.RowCount - 1 do
begin
with IbStoredProc1 do
begin
Close;
IbStoredProc1.StoredProcName := 'ACTUALIZA_VALESDETALLE';
ParamByName('VID_VALE').AsString := VCodigo;
ParamByName('VID_PRODUCTO').AsString := StringGrid1.Cells[4,a];
ParamByName('VCANTIDAD').AsFloat := StrToFloat(StringGrid1.Cells[0,a]);
ParamByName('VDESCRIPCION').AsString := StringGrid1.Cells[1,a];
ParamByName('VVALORUNITARIO').AsInteger := StrToInt(StringGrid1.Cells[2,a]);
ParamByName('VTOTAL').AsInteger := Total;
Prepare;
ExecProc;
VFlag := ParamByName('FLAG').AsInteger;
end;
if VFlag = 1 then
Break;
end;
Label6.Caption := IntToStr(VFlag);
if VFlag = 1 then
begin
IbTransaction1.RollBack;
s := StringGrid1.Cells[0,a] + ' ' + StringGrid1.Cells[1,a];
MessageDlg('Registro ' + s + ' no tiene stock suficiente',mtError,[mbOk], 0);
end
else
IbTransaction1.Commit;
end;
end;

En base a lo planteado, que debo hacer para manejar el lock_conflict


Muchas gracias.
Responder Con Cita
  #2  
Antiguo 03-11-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Exception conflicto

Es decir, te creas una excepción y desde ahí la lanzas, Firebird deshace los cambios de forma automática según el caso:

- Si es un SP de SELECT, puede haber varios SUSPEND, solo se deshace los cambios desde el último SUSPEND;
- Si es un SP ejecutable, no debe haber SUSPEND, por tanto se deshace el SP al completo.

Deberias olvidarte del Flag, y especificar el mensaje directamente en la excepción creada.
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #3  
Antiguo 03-11-2005
Carlos Hurtado Carlos Hurtado is offline
Miembro
 
Registrado: dic 2004
Posts: 30
Poder: 0
Carlos Hurtado Va por buen camino
Hola Amigos, un saludo Lepe. Muy agradecido de tu sugerencia.
pero me gustaria profundizar mas sobre el tema.

Como se desprende del codigo Delphi la procedure Actualiza_ValesDetalle se repite tantas veces como lineas tenga el stringgrid que alimenta la tabla Detalle (ValesDetalle). Por lo tanto si ocurre un error del tipo lock_conflict es porque el Parametro nowait no permitio actualizar la transaccion ya que habia que esperar que terminara otra en proceso.
Pues bien, lo que yo pienso es que si sucede un lock_conflict lo logico seria poder repetir la procedure ya que al hacerlo no existiria la condicion de lock_conflict y me permitiria hacer el commit de toda la transaccion.
Por eso insisto como puedo hacer que este codigo me haga repetir la instruccion de update:

WHEN GDSCODE lock_conflict DO
BEGIN
¡¡¡¡NO SE QUE HACER!!!
END

Ojala haya alguna sugerencia.
Muchas gracias.
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 07:39:47.


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