Las excepciones son una importante herramienta que el Firebird pone a nuestra disposición para que las utilicemos cuando ocurre un error dentro de un stored procedure o de un trigger.

¿Qué significa “capturar una excepción”?

Que podemos decidir nosotros lo que se hará cuando ocurre un error, en lugar de dejar que el Firebird haga sus acciones predeterminadas.

Por lo tanto:

    • Si no capturamos la excepción, el Firebird decide que acción tomar
    • Si capturamos la excepción, nosotros decidimos que acción tomar

¿Dónde se pueden capturar las excepciones?

En los stored procedures y en los triggers

 ¿Cómo se llama el bloque de comandos que nosotros escribimos para decidir qué acción tomar cuándo ocurre un error?

Manejador de la excepción

¿Por qué necesitamos escribir manejadores de excepción?

Porque así podemos responder al error y quizás corregirlo

¿Cómo se captura una excepción?

Usando la palabra clave WHEN y un bloque BEGIN … END

¿Cómo se le dice al Firebird cuáles errores se desea controlar?

Con una lista de esos errores, que puede ser:

  1. Código de error SQL de una excepción del sistema
  2. Nombre de una excepción del sistema
  3. Nombre de una excepción del usuario
  4. Escribiendo “ANY” que significa que todos los errores serán manejados

¿Cuáles son las acciones que toma el Firebird cuándo ocurre un error?

  • Busca un manejador para la excepción en el stored procedure o trigger actual
  • Deshace todas las acciones que había realizado hasta ese momento en el stored procedure o trigger actual
  • Regresa al nivel superior y busca un manejador de la excepción allí. Continúa subiendo niveles hasta que encuentra un manejador para la excepción. Si ningún manejador de excepción es encontrado entonces devuelve el control al programa llamador, informándole del error ocurrido
  • Si encontró un manejador para la excepción entonces ejecuta todas las instrucciones que hay en ese manejador de excepción y luego continúa con la línea siguiente a la que invocó al stored procedure o trigger que tenía el error. Si ese stored procedure o trigger estaba en el nivel más alto, entonces el control regresa a la aplicación

Si un error es capturado en un manejador de excepción, entonces no se informa de ese error a la aplicación.

¿Qué significa “relanzar la excepción”?

Que después de capturar la excepción y de manejar el error ocurrido podemos pedirle al Firebird que continúe con sus acciones por defecto, o sea las que hubiera hecho de no haber sido capturada la excepción.

¿Cómo se relanza una excepción?

Escribiendo la palabra:

EXCEPTION;

Sin nada más a su derecha que el punto y coma

¿Qué podemos hacer cuándo ocurre un error?

  1. Nada. En este caso el Firebird se encargará de su manejo
  2. Capturarlo. En este caso nosotros nos encargaremos de su manejo
  3. Capturarlo y relanzarlo. Que es una mezcla de los dos anteriores. Primero, nosotros nos encargamos de su manejo y luego le pedimos al Firebird que se encargue él

Ejemplo 1:

SET TERM ^ ;

CREATE PROCEDURE CAPTURAR_EXCEPCION_1
AS
   DECLARE VARIABLE lnMiNumero INTEGER;
   DECLARE VARIABLE lnResultado INTEGER;
BEGIN

   lnMiNumero = 21;

   lnResultado = lnMiNumero / 0;

END^

SET TERM ; ^

Como puedes ver, aquí hay una división por cero, la cual como seguramente sabes no está permitida en Matemática. Entonces, si ejecutamos ese stored procedure el Firebird nos mostrará el mensaje:

“Arithmetic exception, numeric overflow, or string truncation.

Integer divide by zero. The code attempted to divide an integer value by an integer divisor of zero.
At procedure ‘CAPTURAR_EXCEPCION_1’ line: 9, col: 4.

SQL Code: -802
IB Error Number: 335544321″

¿Qué podríamos escribir para capturar ese error?

Ejemplo 2:

SET TERM ^ ;

CREATE PROCEDURE CAPTURAR_EXCEPCION_2
AS
   DECLARE VARIABLE lnMiNumero INTEGER;
   DECLARE VARIABLE lnResultado INTEGER;
BEGIN

   lnMiNumero = 21;

   lnResultado = lnMiNumero / 0;

   WHEN GDSCODE ARITH_EXCEPT DO BEGIN -- Ocurrió una excepción aritmética

   END

END^

SET TERM ; ^

Aquí le estamos diciendo al Firebird que si ocurre un error aritmético, cualquiera sea ese error, que lo ignore. Como dentro del manejador de la excepción (el bloque WHEN … END es el manejador de la excepción) no hemos escrito algún comando, entonces nada se hará, el efecto será ignorarlo al error ocurrido. Por supuesto que podríamos escribir algo, como vemos a continuación:

Ejemplo 3:

SET TERM ^ ;

CREATE PROCEDURE CAPTURAR_EXCEPCION_3
AS
   DECLARE VARIABLE lnMiNumero INTEGER;
   DECLARE VARIABLE lnResultado INTEGER;
BEGIN

   lnMiNumero = 21;

   lnResultado = lnMiNumero / 0;

   WHEN GDSCODE ARITH_EXCEPT DO BEGIN -- Ocurrió una excepción aritmética
      lnResultado = -999;
   END

END^

SET TERM ; ^

Ahora le estamos diciendo que si ocurre un error de división por cero le asigne a la variable lnResultado el valor -999

Ejemplo 4:

SET TERM ^ ;

CREATE PROCEDURE CAPTURAR_EXCEPCION_4
AS
   DECLARE VARIABLE lnMiNumero INTEGER;
   DECLARE VARIABLE lnResultado INTEGER;
BEGIN

   lnMiNumero = 21;

   lnResultado = lnMiNumero / 0;

   WHEN GDSCODE ARITH_EXCEPT DO BEGIN -- Ocurrió una excepción aritmética
      lnResultado = -999;
      EXCEPTION;
   END

END^

SET TERM ; ^

Aquí estamos haciendo dos cosas cuando ocurre una división por cero. Primero, le asignamos a la variable lnResultado el valor -999 y segundo, le pedimos al Firebird que haga lo que normalmente hace cuando encuentra una división por cero.

Conclusión:

Si capturamos los errores entonces tenemos muchísimo más control sobre lo que ocurre dentro de los stored procedures y de los triggers. Hemos visto varias formas de manejar las excepciones (o sea, los errores) y en siguientes artículos veremos aún más.

Artículos relacionados:

Entendiendo las excepciones

El índice del blog Firebird21

Anuncios