Así como podemos capturar las excepciones del Firebird, las cuales tienen un número en SQLCODE o un código en GDSCODE también podemos capturar nuestras propias excepciones.

Ejemplo:

Tenemos una tabla llamada PRODUCTOS en la cual (además de otros datos) guardamos el precio de costo y el precio de venta de cada producto. Es política de la empresa que nunca el precio de venta pueda ser menor que el precio de costo aumentado en un 5%. En otras palabras, que el porcentaje de ganancia siempre debe ser 5% o más.

Esta es nuestra tabla PRODUCTOS:

CAPTURA1

Captura 1. Si haces clic en la imagen la verás más grande

Y esta es la tabla ERRORES, donde registramos todos los errores que vamos encontrando:

CAPTURA2

Captura 2. Si haces clic en la imagen la verás más grande

Esta es una excepción, que será lanzada cuando el precio de venta sea menor que el precio de costo aumentado en un 5%

CREATE EXCEPTION E_PORCENTAJE_MENOR_5 'El porcentaje de ganancia es menos que el 5%.';

Y este es un trigger de la tabla PRODUCTOS donde validamos que los precios de venta siempre sean al menos un 5% superiores al precio de costo. Y cuando no ocurre eso, insertamos una fila en la tabla ERRORES.

SET TERM ^ ;

CREATE TRIGGER PRODUCTOS_BIU FOR PRODUCTOS
       ACTIVE BEFORE INSERT OR UPDATE
       POSITION 1
AS
BEGIN

   IF (NEW.PRD_PREVTA * 100 / NEW.PRD_PRECTO - 100 < 5) THEN
      EXCEPTION E_PORCENTAJE_MENOR_5
      'El porcentaje de ganancia es menor que el 5%. Producto = ' || NEW.PRD_NOMBRE ;

   WHEN EXCEPTION E_PORCENTAJE_MENOR_5 DO
      IN AUTONOMOUS TRANSACTION DO
         INSERT INTO ERRORES
               (ERR_MODULO, ERR_COMENT)
        VALUES ('PRODUCTOS_BIU' , 'El % de ganancia del producto *' || TRIM(NEW.PRD_NOMBRE) || '* es menor que 5%') ;

END^

SET TERM ; ^

Fíjate que se sobreescribe el mensaje de la excepción y usamos un nuevo mensaje, personalizado, para indicar el nombre del producto que tuvo el problema. Desde luego que no es obligatorio sobreescribir el mensaje de la excepción, podríamos haber usado el mensaje por defecto, pero al sobreescribirlo tenemos más información. También cuando atrapamos la excepción indicamos el nombre del producto problemático para que al revisar la tabla ERRORES sea fácil saber cual fue ese producto.

Si ahora escribimos:


INSERT INTO PRODUCTOS (PRD_IDENTI, PRD_NOMBRE, PRD_PRECTO, PRD_PREVTA)
VALUES (0, 'COCA COLA 1 LITRO', 45, 60)

estará todo bien, ningún problema porque el porcentaje de ganancia es mayor que el 5% (es del 33%)

Sin embargo, si escribimos:


INSERT INTO PRODUCTOS (PRD_IDENTI, PRD_NOMBRE, PRD_PRECTO, PRD_PREVTA)
VALUES (0, 'FANTA NARANJA 1 LITRO', 45, 46)

no se insertará el producto ‘FANTA NARANJA 1 LITRO’ en la tabla PRODUCTOS. ¿Por qué no? porque ocurrió una excepción, (el porcentaje de ganancia es menor que el 5%) y cuando ocurre una excepción todo lo que se había hecho hasta ese momento se desecha. Por lo tanto el INSERT a la tabla PRODUCTOS es desechado. Pero el INSERT a la tabla ERRORES sí funciona, porque ese INSERT estaba dentro de una IN AUTONOMOUS TRANSACTION y por lo tanto se guarda sí o sí.

Si ahora revisamos el contenido de la tabla ERRORES veremos esto:

CAPTURA3

 

Captura 3. Si haces clic en la imagen la verás más grande

Y hemos conseguido lo que buscábamos: que cuando ocurra una excepción del usuario la capturemos.

Conclusión:

Así como podemos capturar las excepciones del Firebird (las que usan SQLCODE y GDSCODE) también podemos capturar nuestras propias excepciones. Siempre es conveniente registrar en una tabla las excepciones ocurridas para más adelante poder revisar esa tabla y descubrir que fue lo que se hizo mal.

Artículos relacionados:

Capturando excepciones

Capturando excepciones. Códigos de error predeterminados

¿Cuáles errores no se pueden atrapar?

El índice del blog Firebird21

Anuncios