Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Problema con Try Except (https://www.clubdelphi.com/foros/showthread.php?t=49211)

Espartaco 16-10-2007 10:12:50

Problema con Try Except
 
Hola amigos de nuevo aquí con mis dudas pidiendo ayuda.

Resulta que en un bucle Try Except realizo varios post, pero el problema es que cuando falla algun post, resulta que los anteriores ya se han grabado en la BD. Mi pregunta es ¿en el bucle try, si falla algo, todo vuelve a su estado anterior?

Uso Delphi 5 y tablas paradox.

el código es el siguiente:
Código Delphi [-]
TRY
        DbLiquid['NMAQUINA']:=DbMaquinas['NMAQUINA'];
        DbLiquid['FLIQUID']:=DateTimePicker1.Date;
        DbLiquid['HUCHA']:=DbEdit1.Text;
        DbLiquid['RECAUDACION']:=DbEdit2.Text;
        DbLiquid['EXCAMBIO']:=DbEdit3.Text;
        DbLiquid['LECTURAX']:=DbEdit4.Text;
        DbLiquid['LECTURAZ']:=DbEdit5.Text;
        DbLiquid['UBICACION']:=DbMaquinas['UBICACION'];
        DbLiquid['DOMICILIO']:=DbMaquinas['DOMICILIO'];
        DbLiquid['NIF']:=DbMaquinas['NIF'];
        DbLiquid['OBSERVACIONES']:=Edit46.Text;
        DbLiquid['CARGADOR']:=DbLookupComboBox1.Text;
        DbLiquid['BILLETES']:=DbEdit6.Text;
        DbLiquid['PORCENTAJE']:=DbMaquinas['PORCENTAJE'];
        DbLiquid['FULTLIQ']:=DateTimePicker1.Date;
        DbLiquid.Post;
        if DbDevoluc.Locate('NMAQUINA',DbMaquinas['NMAQUINA'],[]) then
        begin
        DbDevoluc.Edit;
        DbDevoluc['FULTLIQ']:=DateTimePicker1.Date;
        DbDevoluc.Post;
        end
        else
        begin
        DbDevoluc.Append;
        DbDevoluc['NMAQUINA']:=DbMaquinas['NMAQUINA'];
        DbDevoluc['FULTLIQ']:=DateTimePicker1.Date;
        DbDevoluc.Post;
        end;
        for i:=0 to 41 do
        begin
                if (ALabels[i].Caption<>'') and (AEdits[i].Text<>'') then
                begin
                DbDLiquid.Append;
                DbDLiquid['NMAQUINA']:=DbMaquinas['NMAQUINA'];
                DbDLiquid['FLIQUID']:=DateTimePicker1.Date;
                DbDLiquid['ABREVIA']:=ALabels[i].Caption;
                //DbDLiquid['UNIDADES']:=AEdits[i].Text;
                DbProducto.Locate('ABREVIA',ALabels[i].Caption,[]);
                DbDLiquid['PRODUCTO']:=DbProducto['PRODUCTO'];
                DbDLiquid['VENTAS']:=AEdits[i].Text;
                DbDLiquid['EXISTENCIAS']:=AEdits2[i].Text;
                DbDLiquid.Post;
                end;
        end;
        for i:=0 to 41 do
        begin
                if (ALabels[i].Caption<>'') and (AEdits[i].Text<>'') then
                begin
                if not DbResultPL.Locate('NMAQUINA;ABREVIA', VarArrayOf([DbMaquinas['NMAQUINA'],ALabels[i].Caption]),[])then
                begin
                        DbResultPL.Append;
                        DbResultPL['NMAQUINA']:=DbMaquinas['NMAQUINA'];
                        DbResultPL['FLIQUID']:=DateTimePicker1.Date;
                        DbResultPL['ABREVIA']:=ALabels[i].Caption;
                        DbProducto.Locate('ABREVIA',ALabels[i].Caption,[]);
                        DbResultPL['PRODUCTO']:=DbProducto['PRODUCTO'];
                        DbResultPL['EXISTANT']:=AEdits2[i].Text;
                        DbResultPL['PRCOSTO']:=DbProducto['PRCOSTO'];
                        DbResultPL['PRPUBLICO']:=DbProducto['PRPUBLICO'];
                        DbResultPL['TOTCOSTO']:=DbResultPL['ENTRADAS']*DbResultPL['PRCOSTO'];
                        DbResultPL['TOTPUBLICO']:=DbResultPL['ENTRADAS']*DbResultPL['PRPUBLICO'];
                        DbResultPL.Post;
                end
                else
                begin
                        DbResultPL.Edit;
                        DbResultPL['EXISTANT']:=AEdits2[i].Text;
                        DbResultPL.Post;
                end;
                end;
        end;
        QDatos.Close;
        Close;
except
        application.MessageBox('¡HA OCURRIDO UN ERROR AL INTENTAR GRABAR LOS DATOS!'+#13+#13+
        'Compruebe:'+#13+'- Si los campos obligatorios están rellenos.',
        '¡Atención!', mb_iconStop + mb_Ok);
        end

Muchas gracias por vuestra ayuda.

gluglu 16-10-2007 10:19:05

En un bucle Try .. Except, si se produce un error o excepción, el programa salta desde la línea que en ese momento se encuentre en ejecución, y en la cual se produzca el error, a la siguiente línea que aparezca después del Except.

Eso no significa para nada que las líneas anteriores no se hayan ejecutado y por lo tanto, si realizas Post estos sigan vigentes.

Si lo que quieres es cancelar los Post realizados, deberás pensar en la transacción asociada y realizar un RollBack según corresponda.

;)

Espartaco 16-10-2007 10:26:46

Gracias gluglu por tu rapida respuesta, pero podrías orientarme un poco acerca de la transaccion asociada y del rollback que me comentas.

Gracias de nuevo.

gluglu 16-10-2007 10:45:48

El tema de las transacciones es un tema que no es inmediato y que lamento no poder reducirte a unas cuantas líneas en un hilo.

Te recomiendo empieces por este documento de un compañero del Club, y además en este hilo se habla sobre todo del tema y encontrarás otros varios enlaces adicionales.

En cualquier caso, y perdona que te remita a ella, encontrarás inmensa cantidad de ayuda en la búsqueda del foro respecto al tema de transacciones, así como acerca del RollBack.

;)

Espartaco 16-10-2007 10:57:15

Muchas gracias gluglu, mirare lo que me has dicho, y si tengo alguna duda pondre otro hilo.

Gracias de nuevo.

eduarcol 16-10-2007 14:24:35

muy buena explicacion gluglu, pero un pequeño detalle, en el caso que nos plantea el compañero se trata de tablas Paradox por lo que el asunto de las transacciones le queda grande.

En los componentes BDE se puede utilizar algo llamado cacheupdate, en ese caso las lineas antes del except deberian ser el applyupdate de cada tabla, y en el caso del except el cancelupdate

Espero te sirva y cualquier cosa preguntas, la ayuda de Delphi plantea muy bien ese punto.

Caro 16-10-2007 14:46:57

Hola Espartaco, te pongo un ejemplo, con BDE y ADO.

Código Delphi [-]
  //BDE
  Database1.StartTransaction;//inicias la transacción
  try
    //Inserciones, modificaciones o eliminaciones sobre la base de datos
    Database1.Commit;//aceptas las operaciones de la base de datos
  except
   Database1.Rollback;//deshace las operaciones realizadas sobre la BD
   showmessage('Se ha producido un error');
   raise;
  end;//try

 //ADO  
 ADOConnection1.BeginTrans;
 try
   //Inserciones, modificaciones o eliminaciones sobre la base de datos 
   ADOConnection1.CommitTrans;
 except
   ADOConnection1.RollbackTrans;
   showmessage('Se ha producido un error'); 
   raise;
 end;//try


Saluditos

Espartaco 17-10-2007 13:34:29

Efectivamente eduarcol, he mirado el link de gluglu pero es para firebird.

Al ejemplo de caro me surgen algunas dudas:

- Para utilizar este codigo imagino que no tengo que añadir ninguna libreria.

- Tengo que insertar en el form algun componente?

- y por ultimo, donde pones

Cita:

//Inserciones, modificaciones o eliminaciones sobre la base de datos
puedo poner operaciones para mas de una tabla con sus post correspondientes?

Muchas gracias a todos por vuestra ayuda.:)

kuan-yiu 17-10-2007 13:46:37

Sí, puedes poner todas las operaciones que necesites siempre que formen "un conjunto lógico".
No pongas más de lo que necesites porque cuanto mayor sea la transacción más lento se vuelve el rollback en caso de fallo y más espacio se necesita para éste.

Espartaco 25-10-2007 09:31:49

Antes que nada perdon por tardar en probar las transacciones, pero el trabajo manda, y dar las gracias por vuestra ayuda.

He probado las transacciones como pone Caro, pero tengo un problema, que seguramente sera porque es la primera vez que utilizo esto y algo se me habra pasado.

El caso es que me da un error
Cita:

The transaction isolation level must be dirty read for local databases
y no se por que ocurre.

He insertado en el form un componente Database y en la propiedad DatabaseName he puesto el nombre del alias de la base de datos que utilizo. Antes de esto ya tenia insertados los componentes TTable y TDataSource correspondientes, a estos componentes no les he tocado despues de insertar el componente Database.

No se si me he explicado, creo que si. Gracias de nuevo.

Espartaco 27-10-2007 13:35:54

Solo para que se refresque el post en la lista y no se pierda, pues necesito la ayuda, espero me contesteis pronto.

Muchas gracias.

Espartaco 31-10-2007 14:36:25

Me respondo yo.

El error era que no ponia la propiedad TransIsolation del DataBase en Dirty Read, que es obligatorio para bases de datos locales.

Gracias a todos por vuestra ayuda.


La franja horaria es GMT +2. Ahora son las 03:04:56.

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