Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Deshacer accion realizada por un ADOCOmmand (https://www.clubdelphi.com/foros/showthread.php?t=77067)

mizzard 17-12-2011 19:33:10

Deshacer accion realizada por un ADOCOmmand
 
Hola a todos, uso C++Builder y me encuentro en la fase de depuración de un programita que estoy haciendo.

El caso es que se me ha ocurrido que puede darse el caso de que el usuario se equivoque a la hora de seleccionar una opcion y desee deshacer el ultimo cambio hecho. El caso es que depende de la opcion seleccionada el ADOCommand que utilizo realiza unas acciones u otras.

De momento se me ha ocurrido sacar una ventana de notificación de los cambios para que el usuario acepte.

Pero.... sabeis si existe la posibilidad de deshacer los ultimos cambios realizados por el ADOCommand? (Teniendo en cuenta que el componente sigue teniendo la propiedad CommandText intacta aún)


Muchas gracias y un saludo!

ecfisa 17-12-2011 21:07:31

Hola mizzard.

Mi conocimiento de los componentes ADO es muy pobre, pero... ¿ Has probado con el método RollbackTrans del TADOConnection ?

Según la ayuda de Builder:
Cita:

Description
Call RollbackTrans to cancel any changes made during the current transaction and to end the transaction.
...

Un saludo.

mizzard 19-12-2011 01:36:19

Hola, hasta donde tengo entendido eso es para poder realizar varios cambios con ADOCommand como si fuera uno único y si alguno de ellos da error, se cancelan todos. Para ello se sigue la siguiente estructura:

Código:

frmPrincipal->DBConnectionTiMesDB->BeginTrans();
    try{
                strSQL = "UPDATE Digitalizado SET FechaOut = " +  fecha  + ", HoraOut= " + hora + " WHERE Id= " + frmPrincipal->DBtxtContador->Caption;
                frmPrincipal->cmdTiMes->CommandText = strSQL;
                frmPrincipal->cmdTiMes->Execute();

                // Restamos las fechas para calcular el tiempo de proceso
                resultadoProceso = restarFechas();

                // Metemos el resultado en la base de datos
                strSQL = "UPDATE Digitalizado SET TiempoTotal = " +  resultadoProceso + " WHERE Id= " + frmPrincipal->DBtxtContador->Caption;
                frmPrincipal->cmdTiMes->CommandText = strSQL;
                frmPrincipal->cmdTiMes->Execute();
                frmPrincipal->DBConnectionTiMesDB->CommitTrans();
                }
                catch(...){
                            frmPrincipal->DBConnectionTiMesDB->RollbackTrans();
                }

Yo lo que quisiera es mediante un boton cancelar la operación realizada (y se supone que exitosa).

Otra duda que me surge es como probar si el rollbackTrans que he implementado funciona o no. He probado a provocar un error en el segundo command (cambiando un TiempoTotal por TiemoTotal) y me salta un error en access pero no salta el catch ni se activa el rollback.

Ideas??

Muchas gracias y un abrazo!

mizzard 19-12-2011 01:49:33

Cita:

Empezado por mizzard (Mensaje 421529)
Hola, hasta donde tengo entendido eso es para poder realizar varios cambios con ADOCommand como si fuera uno único y si alguno de ellos da error, se cancelan todos. Para ello se sigue la siguiente estructura:

Código:

frmPrincipal->DBConnectionTiMesDB->BeginTrans();
    try{
                strSQL = "UPDATE Digitalizado SET FechaOut = " +  fecha  + ", HoraOut= " + hora + " WHERE Id= " + frmPrincipal->DBtxtContador->Caption;
                frmPrincipal->cmdTiMes->CommandText = strSQL;
                frmPrincipal->cmdTiMes->Execute();

                // Restamos las fechas para calcular el tiempo de proceso
                resultadoProceso = restarFechas();

                // Metemos el resultado en la base de datos
                strSQL = "UPDATE Digitalizado SET TiempoTotal = " +  resultadoProceso + " WHERE Id= " + frmPrincipal->DBtxtContador->Caption;
                frmPrincipal->cmdTiMes->CommandText = strSQL;
                frmPrincipal->cmdTiMes->Execute();
                frmPrincipal->DBConnectionTiMesDB->CommitTrans();
                }
                catch(...){
                            frmPrincipal->DBConnectionTiMesDB->RollbackTrans();
                }

Yo lo que quisiera es mediante un boton cancelar la operación realizada (y se supone que exitosa).

Otra duda que me surge es como probar si el rollbackTrans que he implementado funciona o no. He probado a provocar un error en el segundo command (cambiando un TiempoTotal por TiemoTotal) y me salta un error en access pero no salta el catch ni se activa el rollback.

Ideas??

Muchas gracias y un abrazo!

Si que funciona el rollback en este código, que al probarlo en modo debug no se ve, pero cuando se prueba el ejecutable si que funciona.

Lo que no consigo es deshacer el último cambio por boton de deshacer... :(

ecfisa 19-12-2011 04:34:26

Cita:

Lo que no consigo es deshacer el último cambio por boton de deshacer...
Hola mizzard.

No entiendo bién eso último, ¿ es decir que no te funciona si haces ?
Código:

void __fastcall TForm1::btnDeshacerClick(TObject *Sender)
{
  frmPrincipal->DBConnectionTiMesDB->RollbackTrans();
}

Un saludo.

mizzard 19-12-2011 12:27:23

Cita:

Empezado por ecfisa (Mensaje 421533)
Hola mizzard.

No entiendo bién eso último, ¿ es decir que no te funciona si haces ?
Código:

void __fastcall TForm1::btnDeshacerClick(TObject *Sender)
{
  frmPrincipal->DBConnectionTiMesDB->RollbackTrans();
}

Un saludo.


Hola, el caso es q haciendo pruebas intenté eso mismo y no funcionaba y debugeando código llegue a la siguiente conclusion:

Basandonos en el trozo q he puesto con try y catch si se produce algun error (no llega a ejecutarse el CommitTrans) por lo que el RollbackTrans sí que funciona. Si todo se efectua correctamente (se ejecuta todo el codigo del try incluyendo el commitTrans -> que es cuando se llevan a cabo todas las modificaciones en la base de datos) si luego intentas ejecutar el RollbackTrans, el compilador da error de que no existe ninguna transaccion abierta (Ya que se ha validado todo con el CommitTrans).

Mmm, no se si me he explicado del todo bien, pero básicamente en el momento que se ejecuta el CommitTrans y se actualiza todo no consigo ver la forma de deshacer los cambios.


Un saludo!

ecfisa 19-12-2011 15:12:46

Hola.

Si ahora entendí. Y es totalmente lógico, ya que CommitTrans almacena todos los cambios y finaliza la transacción actual.

Creo que para lograr el efecto que buscas deberías comenzar la transacción, permitir todos los cambios que desee el usuario y dejarle la opción de cancelar (RollBackTrans) o aceptar (CommitTrans) por el medio que consideres adecuado; botones, cuadro de diálogo, etc.


Un saludo.

mizzard 08-01-2012 23:24:26

;), lo mismo que habia pensado.

Muchas gracias, un abrazo!


La franja horaria es GMT +2. Ahora son las 03:43:27.

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