You are on page 1of 28

Disparadores (triggers)

 Un trigger o disparador es un procedimiento


almacenado que se asocia con una tabla
específica. Se pueden usar disparadores para
personalizar la reacción de un servidor de base de
datos.
 El disparador define una acción que la base de
datos debe llevar a cabo cuando se produce algún
suceso relacionado con la misma.
 Los disparadores pueden utilizarse para
complementar la integridad referencial declarativa,
para imponer reglas del negocio complejas o para
auditar cambios en los datos.
 El código contenido en un disparador,
denominado cuerpo del disparador, está formado
por bloques PL/SQL.
 La ejecución de disparadores es transparente
para el usuario.
 La base de datos ejecuta los disparadores cuando
algunos tipos específicos de comandos de
manipulación de datos (DML) se ejecutan en
tablas específicas: Ej INSERT, UPDATE,
DELETE.
 La ejecución del disparador también se puede
activar cuando se actualizan campos específicos
de tablas.
 Para crear un trigger el usuario deberá tener el
privilegio de sistema CREATE TRIGGER o ser un
usuario DBA.
 Además deberá ser propietario de la tabla sobre
la cual se desea crear el trigger, tener privilegios
de ALTER sobre la tabla específica o tener el
privilegio ALTER ANY TABLE.
 Para crear un disparador en el esquema de otro
usuario, se debe tener el privilegio CREATE ANY
TRIGGER.
 Para modificar el disparador, lo debe hacer el
propietario del mismo o tener el privilegio de
ALTER ANY TRIGGER
 Para ejecutar un trigger que deba insertar,
modificar o eliminar registros en alguna tabla, el
usuario deberá tener los privilegios de objeto
correspondientes.
Tema 5.1
 Un tipo de disparador se define mediante el tipo
de transacción de disparo y el nivel con el que se
ejecuta el disparador.
 Se tienen los siguientes tipos de disparadores:
◦ Disparadores de nivel de fila
◦ Disparadores de nivel de instrucción
◦ Disparadores BEFORE Y AFTER
◦ Disparadores INSTEAD OF
◦ Disparadores de esquema
◦ Disparadores en el nivel de base de datos
 Se ejecutan una vez para cada fila afectada por
una instrucción DML
 Son el tipo más común de disparador.
 Los disparadores de nivel de fila se crean
utilizando la cláusula for each row en el comando
create trigger.
 Se ejecutan una vez cada instrucción DML.
 Ejemplo: Si una única instrucción INSERT inserta
500 filas en una tabla, un disparador de nivel de
instrucción para dicha tabla, sólo se ejecutará una
vez.

 No se utilizan a menudo para actividades


relacionadas con los datos; generalmente se
emplean para imponer medidas de seguridad
adicionales sobre los tipos de acciones que se
pueden llevar a cabo en una tabla
 Puesto que los disparadores son ejecutados por
sucesos, puede establecerse que se produzcan
inmediatamente antes (before) o después (after)
de dichos sucesos.
 Ejemplo, los disparadores se pueden ejecutar
antes o después de instrucciones de inserción,
modificación o eliminación.
 Dentro del disparador se puede hacer referencia a
los valores antiguos o nuevos implicados en las
instrucciones DML.
 Los valores antiguos (old) hacen referencia a los
datos tal y como eran antes de la instrucción
DML; normalmente las instrucciones update y
delete hacen referencia a los valores antiguos.
 Los valores nuevos son los valores de datos que
la instrucción DML crea, como en caso de las
columnas de un registro insertado.
 Se usan para indicar a Oracle lo que tiene que
hacer en lugar de realizar las acciones que invoca
el disparador. Ejemplo, se puede usar este tipo de
disparador para actualizar distintas tablas
involucradas en una vista.
 El contenido del disparador se ejecuta en vez del
comando INSERT, UPDATE o DELETE que se
haya ejecutado sobre la vista.
 Se pueden crear disparadores para istrucciones
como create table, alter table, drop table, truncate,
revoke.
 Por ejemplo, se puede crear un trigger para evitar
que un usuario elimine sus propias tablas.
 Estos disparadores impiden o controlan
operaciones DDL.
 Se pueden crear disparadores que se activen al
producirse sucesos en la base de datos, como
errores, inicios de sesión, cierres de sesión, etc.
Tema 5.2
CREATE OR REPLACE TRIGGER
nombre_disparador
{BEFORE | AFTER | INSTEAD OF}
{cláusula_suceso_dml | suceso ddl | susceo de
base de datos}
ON {equema| base de datos}
[WHEN (condición) ]
{bloque PL/SQL |
instrucción_llamada_procedimiento}
 La sintaxis del trigger cambia dependiendo del
tipo.
 Ejemplo:
 Un disparador definido sobre un suceso DML
utilizará el parámetro cláusula_suceso_dml cuya
sintaxis es la siguiente:
{DELETE | INSERT | UPDATE [OF columna1, columna2, …]}
ON esquema.tabla
FOR EACH ROWM

Si no se usa la instrucción FOR EACH ROW


Oracle entenderá que se trata de un
disparador de nivel de instrucción
CREATE OR REPLACE TRIGGER cambio_calif_alumno
BEFORE UPDATE ON alumnos
FOR EACH ROW
WHEN (new.calificacion > old.calificacion)
BEGIN
INSERT INTO auditoria_calificaciones
(matricula, nombre_alu, materia, clave_prof,
calif_anterior, calif_nueva, fecha_cambio)
VALUES (:old.matricula, :old.nombre_alu, :old.materia, :old.clave_prof,
:old.calificacion, :new.calificacion, sysdate);
END;

Este es un ejemplo de disparador para


auditoría
CREATE OR REPLACE TRIGGER aviso
AFTER INSERT
ON clientes
BEGIN
DBMS_OUTPUT.PUT_LINE('REGISTRO INSERTADO');
END;
CREATE OR REPLACE TRIGGER inventario
BEFORE INSERT
ON productos
FOR EACH ROW
DECLARE
prod NUMBER(10);
BEGIN
SELECT COUNT(*) INTO prod
FROM productos;
DBMS_OUTPUT.PUT_LINE('HAY OTROS' || prod || '
productos');
END;
CREATE OR REPLACE TRIGGER registro_multa
AFTER UPDATE OF Pr_FecDevR ON prestamos
FOR EACH ROW
DECLARE
dias_retraso NUMBER(2);
pago_total NUMBER(8);
BEGIN
IF :new.Pr_FecDevR > :old.Pr_FecDevT THEN
dias_retraso := :new.Pr_FecDevR - :old.Pr_FecDevT;
pago_total := dias_retraso * 15;
INSERT INTO multas (Mu_FechaMulta, Us_Clave, Mu_DiasRetraso,
Mu_PagoTotal, Mu_Estatus)
VALUES (SYSDATE, :old.us_clave, dias_retraso, pago_total, null);
ELSE
DBMS_OUTPUT.PUT_LINE ('Registro modificado');
END IF;
END;
UPDATE PRESTAMOS SET PR_FECDEVR = '18/02/2009'
WHERE PR_FECPREST = '13/02/2009' AND LI_CVELIBRO = 'QA76.9D P4'
AND LI_COPIA = 1;