Saltar la navegación

5.1.- Definición de disparadores de Tablas

Ilustración en la que se ven dos chicos, un cañón y se puede leer “Bang!”.
ITE (Loren) (Uso educativo nc)


De los tres tipos de disparadores, veremos los asociados a tablas.

Por lo visto anteriormente, para definir un disparador deberemos indicar si será lanzado antes o después de la ejecución de la sentencia que lo lanza, si se lanzará una vez por sentencia o una vez por fila a la que afecta, y si será lanzado al insertar y/o al actualizar y/o al borrar.

La sintaxis que seguiremos para definir un disparador será la siguiente:

CREATE [OR REPLACE] TRIGGER nombre 
momento acontecimiento ON tabla
[[REFERENCING (old AS alias_old|new AS alias_new) 
FOR EACH ROW 
[WHEN condicion]]
bloque_PL/SQL;

Donde nombre nos indica el nombre que le damos al disparador, momento nos dice cuando será lanzado el disparador (BEFORE o AFTER), acontecimiento será la acción que provoca el lanzamiento del disparador (INSERT y/o DELETE y/o UPDATE). REFERENCING y WHEN sólo podrán ser utilizados con disparadores para filas. REFERENCING nos permite asignar un alias a los valores NEW o/y OLD de las filas afectadas por la operación, y WHEN nos permite indicar al disparador que sólo sea lanzado cuando sea TRUE una cierta condición evaluada para cada fila afectada.

En un disparador de fila, podemos acceder a los valores antiguos y nuevos de la fila afectada por la operación, referenciados como :old y :new (de ahí que podamos utilizar la opción REFERENCING para asignar un alias). Si el disparador es lanzado al insertar, el valor antiguo no tendrá sentido y el valor nuevo será la fila que estamos insertando. Para un disparador lanzado al actualizar el valor antiguo contendrá la fila antes de actualizar y el valor nuevo contendrá la fila que vamos actualizar. Para un disparador lanzado al borrar sólo tendrá sentido el valor antiguo.

En el cuerpo de un disparador también podemos acceder a unos predicados que nos dicen qué tipo de operación se está llevando a cabo, que son: INSERTING, UPDATING y DELETING.

Un disparador de fila no puede acceder a la tabla asociada. Se dice que esa tabla está mutando. Si un disparador es lanzado en cascada por otro disparador, éste no podrá acceder a ninguna de las tablas asociadas, y así recursivamente.

CREATE TRIGGER prueba BEFORE UPDATE ON agentes
FOR EACH ROW
BEGIN
     ...
     SELECT identificador FROM agentes WHERE ...     
/*devolvería el error ORA-04091: table AGENTES is mutating, trigger/function may not see it*/
     ...
END;
/

Si tenemos varios tipos de disparadores sobre una misma tabla, el orden de ejecución será:

  • Triggers before de sentencia.
  • Triggers before de fila.
  • Triggers after de fila.
  • Triggers after de sentencia.

Existe una vista del diccionario de datos con información sobre los disparadores: USER_TRIGGERS;

SQL>DESC USER_TRIGGERS;
Name                            Null?    Type
------------------------------- -------- ----
TRIGGER_NAME                    NOT NULL VARCHAR2(30)
TRIGGER_TYPE                             VARCHAR2(16)
TRIGGERING_EVENT                         VARCHAR2(26)
TABLE_OWNER                     NOT NULL VARCHAR2(30)
TABLE_NAME                      NOT NULL VARCHAR2(30)
REFERENCING_NAMES                        VARCHAR2(87)
WHEN_CLAUSE                              VARCHAR2(4000)
STATUS                                   VARCHAR2(8)
DESCRIPTION                              VARCHAR2(4000)
TRIGGER_BODY                             LONG