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;