146 - Disparador (Instead Off y after) |
Hasta el momento hemos aprendido que un trigger se crea sobre una tabla específica para un evento (inserción, eliminación o actualización).
También podemos especificar el momento de disparo del trigger. El momento de disparo indica que las acciones (sentencias) del trigger se ejecuten luego de la acción (insert, delete o update) que dispara el trigger o en lugar de la acción.
La sintaxis para ello es:
create triggre NOMBREDISPARADOR on NOMBRETABLA o VISTA MOMENTODEDISPARO-- after o instead of ACCION-- insert, update o delete as SENTENCIAS
Entonces, el momento de disparo especifica cuando deben ejecutarse las acciones (sentencias) que realiza el trigger. Puede ser "después" (after) o "en lugar" (instead of) del evento que lo dispara.
Si no especificamos el momento de disparo en la creación del trigger, por defecto se establece como "after", es decir, las acciones que el disparador realiza se ejecutan luego del suceso disparador. Hasta el momento, todos los disparadores que creamos han sido "after".
Los disparadores "instead of" se ejecutan en lugar de la acción desencadenante, es decir, cancelan la acción desencadenante (suceso que disparó el trigger) reemplazándola por otras acciones.
Veamos un ejemplo. Una empresa almacena los datos de sus empleados en una tabla "empleados" y en otra tabla "clientes" los datos de sus clientes. Se crea una vista que muestra los datos de ambas tablas:
create view vista_empleados_clientes as select documento,nombre, domicilio, 'empleado' as condicion from empleados union select documento,nombre, domicilio,'cliente' from clientes;
Creamos un disparador sobre la vista "vista_empleados_clientes" para inserción, que redirija las inserciones a la tabla correspondiente:
create trigger DIS_empleadosclientes_insertar on vista_empleados_clientes instead of insert as insert into empleados select documento,nombre,domicilio from inserted where condicion='empleado' insert into clientes select documento,nombre,domicilio from inserted where condicion='cliente';
El disparador anterior especifica que cada vez que se ingresen registros en la vista "vista_empleados_clientes", en vez de (instead of) realizar la acción (insertar en la vista), se ejecuten las sentencias del trigger, es decir, se ingresen los registros en las tablas correspondientes.
Entonces, las opciones de disparo pueden ser:
a) "after": el trigger se dispara cuando las acciones especificadas (insert, delete y/o update) son ejecutadas; todas las acciones en cascada de una restricción "foreign key" y las comprobaciones de restricciones "check" deben realizarse con éxito antes de ejecutarse el trigger. Es la opción por defecto si solamente colocamos "for" (equivalente a "after").
La sintaxis es:
create triggre NOMBREDISPARADOR on NOMBRETABLA after | for-- son equivalentes ACCION-- insert, update o delete as SENTENCIAS
b) "instead of": sobreescribe la acción desencadenadora del trigger. Se puede definir solamente un disparador de este tipo para cada acción (insert, delete o update) sobre una tabla o vista.
Sintaxis:
create triggre NOMBREDISPARADOR on NOMBRETABLA o VISTA instead of ACCION-- insert, update o delete as SENTENCIAS
Consideraciones:
- Se pueden crear disparadores "instead of" en vistas y tablas.
- No se puede crear un disparador "instead of" en vistas definidas "with check option".
- No se puede crear un disparador "instead of delete" y "instead of update" sobre tablas que tengan una "foreign key" que especifique una acción "on delete cascade" y "on update cascade" respectivamente.
- Los disparadores "after" no pueden definirse sobre vistas.
- No pueden crearse disparadores "after" en vistas ni en tablas temporales; pero pueden referenciar vistas y tablas temporales.
- Si existen restricciones en la tabla del disparador, se comprueban DESPUES de la ejecución del disparador "instead of" y ANTES del disparador "after". Si se infringen las restricciones, se revierten las acciones del disparador "instead of"; en el caso del disparador "after", no se ejecuta.