FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Continuar Procedure a pesar del salto de excepción
Hola a tod@s,
tengo un problema con un procedure. BBDD: firebird 1.5 El procedure realiza una serie de inserts según unas condiciones. En el último insert de este procedure y que inserta en una determinada tabla X, salta una excepción. Pusimos una excepción en un trigger before insert que si no se cumple otra condición no se realice el insert en la tabla X i salte esta excepción para capturarla y mostrarla por pantalla en la aplicación delphi. El problema viene que al saltar la excepción en esta última tabla X, el resto de inserts anteriores no se guardan. Hace rollback cuando salta la excepción. Quisiera saber si existe la posibilidad de que aunque salte la excepción del procedure firebird, continúe con el procedure y haga finalmente commit del mismo. Un saludo y gracias por adelantado. |
#2
|
||||
|
||||
A pesar de que lo mejor sería verificar si se va a dar la excepción y actuar en consecuencia, existe una posibilidad:
WHEN XXX DO
|
#3
|
|||
|
|||
Continuar Procedure a pesar del salto de excepción
Hola duilioisola,
he probado de poner el código que me comentas. En concreto he probado en mi procedure:
Ambas opciones han salido con rollback del procedure así que todavía no me queda resuelto el problema. No sé como hacer para que aun saltando una excepción en un insert, el resto de inserts ejecutados anteriormente hagan commit. Última edición por santiaguinillo fecha: 02-06-2008 a las 14:43:08. Razón: poner título |
#4
|
||||
|
||||
Saludos.
Puedes ir haciendo commit por cada inserción es inefectivo pero es una solución. También puedes poner el código que tienes y cuando salte la excepción "forza" el commit.
__________________
Gracias, Rolphy Reyes |
#5
|
|||
|
|||
Hacer commit
Hola RolphyReyes,
el problema es que al poner commit en el procedure me da error al compilar. Es decir, no puedo poner commit dentro del procedure. |
#6
|
||||
|
||||
Prueba con
* when SQLCODE -803 do SUSPEND ; * when EXCEPTION SUPERA_IMPORTE DO SUSPEND ; Cada vez que un procedimiento encuentra un suspend, devuelve los valores que tenga en el RETURNS() y espera a que le pidan el siguiente. Aunque no devuelvas nada, el SUSPEND hará que devuelva el control a tu programa y puedas hacer un commit o rollback, según te convenga. |
#7
|
|||
|
|||
Pruebas con do suspend KO
Hola duilioisola,
¿pero el commit o rollback quieres decir que lo ponga en el código delphi? Porque he hecho lo siguiente y sigue sin hacerme commit (en el procedure he puesto when EXCEPTION SUPERA_IMPORTE DO SUSPEND):
Cita:
Última edición por santiaguinillo fecha: 02-06-2008 a las 16:14:19. |
#8
|
||||
|
||||
Supongo que si no sigue es porque la excepción que salta no es la que esperas en el WHEN EXCEPCION DO...
Prueba a poner WHEN ANY DO... O prueba a ver cuál es la excepción que llega con un ShowMessage.
Por más que le digas que haga un commit, si ha saltado una excepción no grabará los datos. Si quieres envíanos el código de tu procedimiento, para que le hechemos una mirada. Pero como dije anteriormente, quizás sea mejor filtrar los casos para los que se dá la excepción. |
#9
|
|||
|
|||
Un procedimento almacenado funciona como una unidad en donde todas las operaciones son grabadas (commit) si y solamente si no se presenta alguna violacion de integridad (llaves foraneas, primarias, campos nulos, etc). Al presentarse alguna violacion los datos de la base de datos quedan en el estado en que se encontraban justo antes de lanzar el procedimiento almacenado.
Realmente y en lo personal evito que queden datos pendientes por actualizar cuando se lanza un procedimiento almacenado, sin embargo, puedes colocar una sentencia de codigo y que te escriba en otra tabla, no que te lance una expecion porque las excepciones provocan que pierdas las actualzaciones alcanzadas hasta ese punto.
La tabla TS_TRAZO la puedes consultar despues para saber que paso.
__________________
Luis Fernando Buelvas T. |
#10
|
|||
|
|||
Medio solucionado
Hola a todos,
pues resulta que no cogía la excepción correcta. Con el WHEN ANY DO SUSPEND; me ha funcionado correctamente y ha hecho commit de los inserts anteriores. El "problema" es que ahora se traga la excepción y no muestra el mensaje de error ya que el código delphi no detecta excepción. Una pregunta, ¿el insert devuelve alguna variable si se ha insertado correctamente (en el procedure)? Si fuese así, podría devolver en el procedure una variable que diga si se ha insertado bien el último insert que es el único que provoca la excepción. |
#11
|
||||
|
||||
Saludos.
En Firebird 2.xx tienes la clausula RETURNING pero tienes la v1.5. No se cual es tu caso pero analiza si puedes migrar a la nueva versión que tiene más mejoras y estabilidad. Hasta luego.
__________________
Gracias, Rolphy Reyes |
#12
|
||||
|
||||
Si quitas la sentencia WHEN ANY DO SUSPEND de tu procedimiento, la parte donde tratas las excepciones te dirá cuál es la excepción que se ha generado.
De todos modos, la filosofía de las excepciones es diferente a lo que parece que haces tu: - Las excepciones hay que tratar de no utilizarlas. - Consumen muchos recursos. - Si salta una excepción hay que volver atrás todo lo que se ha hecho hasta entonces. - Normalmente se puede evitar la excepción. Por ejemplo: Si tienes un procedimiento que divide dos valores, tienes dos opciones:
Supongo que lo mejor en tu caso (creo que estás insertando registros) es verificar si existe y sobrepasa un valor dado.
Última edición por duilioisola fecha: 03-06-2008 a las 13:56:51. |
#13
|
|||
|
|||
Resuelto
Gracias a todos por vuestras respuestas.
Doy el problema por resuelto. Finalmente con el when any do suspend; ha sido suficiente y aunque ya no muestra el mensaje de la excepción no es realmente grave. Seria interesante haber tenido lo que comentaba RolphyReyes sobre Returning y de esta forma podría haber devuelto alguna variable para informar de que no se ha introducido el último registro. Es para esto que teníamos las excepciones, para informar de ello a la aplicación delphi. Lo que no queríamos es que nos hiciera rollback de las anteriores operaciones en la bbdd del procedimiento. En mi caso no podría hacerlo de otra forma, ni de la forma que comenta duilioisola en el código sql ya que el último insert del procedure se efectua o no dependiendo de unas condiciones que hay en el trigger before insert de la tabla que intenta insertar. Por lo tanto, o bien ponemos el código del trigger en el mismo procedure o bien necesitaríamos el returning que ya tiene el firebird 2.0 De nuevo, gracias a todos por vuestro aporte. Santi. |
#14
|
||||
|
||||
Resp
Dentro de un disparador no vas a poder decir que no inserte o que no haga lo que uba ahacer en su tabla. Por exactamente la accion de insertar es la que dispara el disparador. Lo que si puedes hacer desde el disparador verifcar al condicion que te hace saltar la exception antes de manadar a insertar.
__________________
Todo se puede, que no exista la tecnología aun, es otra cosa. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
continuar una numeracion con Qreport | Alfredo | Impresión | 7 | 23-10-2007 11:05:53 |
Key violation. Continuar con siguiente registro | CHiCoLiTa | Conexión con bases de datos | 11 | 14-02-2007 21:48:37 |
Continuar numeracion en impresion !! Help | RJF | Impresión | 2 | 07-11-2006 04:43:17 |
Desea continuar? SI NO CANCELAR (3 Botones en el formulario) | dmassive | PHP | 3 | 26-08-2005 19:22:08 |
No se continuar | pepelu1975 | Varios | 1 | 19-02-2004 11:02:22 |
|