Desde Firebird 2.1 tenemos la posibilidad de usar triggers de la Base de Datos.

¿Qué es un trigger de la Base de Datos?

Un trigger que se lanza cuando ocurre una de estas condiciones:

  • CONEXIÓN a la Base de Datos
  • DESCONEXIÓN de la Base de Datos
  • INICIO de una Transacción
  • COMMIT de una Transacción
  • ROLLBACK de una Transacción

¿Quiénes pueden crear, modificar o borrar triggers de la Base de Datos?

Solamente el usuario SYSDBA y el creador de la Base de Datos pueden hacerlo

¿Para qué pueden usarse los triggers de la Base de Datos?

  • Para saber quienes se conectaron
  • Para saber quienes se desconectaron
  • Para evitar que se conecten desde una dirección IP
  • Para evitar que se conecte un usuario
  • Para evitar que se conecten fuera de los días establecidos
  • Para evitar que se conecten fuera del horario establecido
  • etc.

Ejemplo 1:

CREATE TRIGGER RegistrarConexion
   ON CONNECT
AS
BEGIN
   INSERT INTO CONEXIONES(CON_USUARI  , CON_TIEMPO, CON_MENSAJ)
                   VALUES(CURRENT_USER, CURRENT_TIMESTAMP, 'Conectado');
END

Este trigger registrará todas las conexiones de los usuarios, con sus fechas y horas, y así podremos saber fácilmente quienes se conectaron y cuando lo hicieron.

Ejemplo 2:

CREATE TRIGGER RegistrarDesconexion
   ON DISCONNECT
AS
BEGIN
   INSERT INTO CONEXIONES(CON_USUARI , CON_TIEMPO, CON_MENSAJ)
      VALUES(CURRENT_USER, CURRENT_TIMESTAMP, 'Desconectado');
END

Con este trigger registramos cada vez que un usuario se desconecta de la Base de Datos. Junto con el anterior nos permitirá saber cuando cada usuario estuvo conectado, si estuvo conectado fuera de las horas laborales, etc.

Ejemplo 3:

CREATE EXCEPTION
   E_ACCESONOPERMITIDO 'Tu dirección de IP no tiene permiso para conectarse a esta Base de Datos' ;

CREATE TRIGGER RegistrarConexion
   ON CONNECT
AS
BEGIN
   IF (EXISTS(SELECT 1 FROM MON$ATTACHMENTS M WHERE M.MON$ATTACHMENT_ID = CURRENT_CONNECTION AND M.MON$REMOTE_ADDRESS = '192.168.0.100')) THEN
      EXCEPTION E_ACCESONOPERMITIDO;
END

En este ejemplo se rechazan todos los intentos de conexión desde la dirección IP 192.168.0.100, nadie podrá conectarse desde esa computadora

Ejemplo 4:

CREATE EXCEPTION
   E_USUARIONOPERMITIDO 'Tú no puedes conectarte a esta Base de Datos, no insistas' ;

CREATE TRIGGER RegistrarConexion ON CONNECT
AS
BEGIN
   IF (EXISTS(SELECT 1 FROM MON$ATTACHMENTS M WHERE M.MON$ATTACHMENT_ID = CURRENT_CONNECTION AND CURRENT_USER = 'JUAN')) THEN
      EXCEPTION E_USUARIONOPERMITIDO;
END

En este ejemplo le impedimos al usuario Juan conectarse, por más que insista no lo logrará.

Ejecución de los triggers de la Base de Datos y el manejo de las excepciones

Los triggers CONNECT y DISCONNECT son ejecutados en una transacción creada específicamente para ellos.

Si todo va bien entonces esa transacción es confirmada (finaliza con un COMMIT) automáticamente. Punto.

Pero si ocurrió una excepción y no fue atrapada entonces se hace el ROLLBACK de la transacción y:

  • En el caso de CONNECT, la conexión es desechada y la excepción se devuelve al Cliente
  • En el caso de DISCONNECT, la conexión es desechada pero la excepción no se devuelve al Cliente

Los triggers de la TRANSACCIÓN son ejecutados dentro de la misma transacción. La acción tomada cuando ocurre una excepción que no fue atrapada depende del tipo de trigger:

  • En un trigger START, la excepción es informada al Cliente y la transacción es desechada
  • En un trigger COMMIT, la excepción es informada al Cliente, las acciones del trigger son desechadas y la grabación es cancelada
  • En un trigger ROLLBACK, la excepción no es informada al Cliente y la transacción es desechada

De lo anterior podemos notar que no hay forma de saber si un trigger DISCONNECT o un trigger ROLLBACK causó una excepción, porque ninguno de ellos se lo informa al Cliente.

También habrás notado que no podremos conectarnos a una Base de Datos si fue el trigger CONNECT el que causó la excepción ni podremos iniciar una transacción si fue el trigger TRANSACTION START el que causó la excepción. Ambos triggers nos impiden que podamos utilizar a la Base de Datos y por lo tanto no podemos solucionar el problema.

¿Cómo se puede evitar que se disparen los triggers de la Base de Datos?

Para que podamos solucionar los errores que hayamos cometido en los triggers CONNECT y TRANSACTION START algunos de los programas que vienen incluidos con el Firebird tienen nuevas opciones:

GBAK -nodbtriggers
ISQL -nodbtriggers
NBACKUP -T

Estas opciones solamente pueden ser usadas por el usuario SYSDBA o por el creador de la Base de Datos.

Si iniciamos el programa ISQL con la opción -nodbtriggers entonces los triggers de la Base de Datos no serán ejecutados, podremos conectarnos a esa Base de Datos, revisar el código fuente de los triggers y solucionar el error que cometimos.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21