Está en la página 1de 15

Disparadores

(Triggers)
Base de Datos II
Ing. Marco Coral

Trigger

Un trigger o un disparador en una BD es un


evento que se ejecuta cuando se cumple una
condicin establecida al realizar una
operacin:

DML statements (DELETE, INSERT, UPDATE)

DDL statements (CREATE, ALTER, DROP)

Database operations (LOGON, LOGOFF)

Con los trigger uno puede automatizar acciones que


usualmente se ejecutan antes o despus de una
consulta, de tal manera que al llevar a cabo la
consulta se dispara la ejecucin de determinadas
acciones, sin intervencin humana.
Los trigger se pueden escribir en estos lenguajes:
C, PL/pgSQL y PL/Tcl. Sin embargo, examinando la
tabla pg_language se puede observar que existe la
referencia a Lisp:

Estructura bsica de un
trigger:

Llamada de activacin: es la sentencia que


permite "disparar" el cdigo a ejecutar,
Restriccin: es la condicin necesaria para
realizar el cdigo. Esta restriccin puede ser
de tipo condicional o de tipo nulidad.
Accin a ejecutar: es la secuencia de
instrucciones a ejecutar una vez que se han
cumplido las condiciones iniciales.

Sintaxis
CREATE [OR REPLACE] TRIGGER nombre
{BEFORE|AFTER|INSTEAD OF} --evento
[WHEN condicin]
{FOR EACH ROW}
--Condicion
BEGIN
cuerpo del trigger
--Accin
END;

Tipos

Existen tipos de triggers, que se clasifican


segn la cantidad de ejecuciones a realizar:

Row Triggers (o Triggers de fila): son quellos


que se ejecutaran n-veces si se llama n-veces
desde la tabla asociada al trigger.
Statement Triggers (o Triggers de secuencia):
son quellos que sin importar la cantidad de
veces que se cumpla con la condicin, su
ejecucin es nica.

Ejemplo: con la opcin


BEFORE

Construir un Trigger que te permita cargar


datos a una tabla a partir d eun evento
update
Paso 1. creamos una tabla temporal
CREATE TABLE sal_temporal (emp_id NUMBER,
fecha DATE, nuevo_sal NUMBER, mensaje
VARCHAR2(50));

Paso 2. creamos el trigger


CREATE OR REPLACE TRIGGER tem_salario
BEFORE UPDATE of salary ON employees FOR
EACH ROW WHEN (OLD.salary < 8000)
BEGIN
INSERT INTO sal_temporal (emp_id, fecha,
nuevo_sal, mensaje) VALUES (:NEW.employee_id,
SYSDATE, :NEW.salary, Fila cargada');
END;
/

Ejecucin

ojo: checar antiguos valores primero)

UPDATE employees SET salary = salary * 1.5


WHERE department_id = 60;
Ver la tabla cargada
SELECT * FROM sal_temporal;

Opcin: AFTER
CREATE TABLE emp_audit ( emp_audit_id NUMBER(6), up_date DATE,
new_sal NUMBER(8,2), old_sal NUMBER(8,2) );
CREATE OR REPLACE TRIGGER audit_sal
AFTER UPDATE OF salary ON employees FOR EACH ROW
BEGIN
INSERT INTO emp_audit VALUES( :OLD.employee_id, SYSDATE,
:NEW.salary, :OLD.salary );
END;
/
Update employees SET salary = salary * 1.01 WHERE manager_id = 122;
SELECT * FROM emp_audit;

Trigger con manejo de


Exception
CREATE TABLE tem_manager (emp_id NUMBER, manager_new NUMBER,
manager_old NUMBER, fecha DATE, mensaje VARCHAR2(50));
CREATE OR REPLACE TRIGGER emp_log_update
BEFORE UPDATE ON employees FOR EACH ROW
DECLARE
manager_diferente EXCEPTION;
BEGIN
IF (:NEW.manager_id <> :OLD.manager_id) THEN
RAISE manager_diferente;
END IF;
INSERT INTO tem_manager (emp_id, manager_new, manager_old, fecha, mensaje)
VALUES (:NEW.employee_id, :NEW.manager_id, :OLD.manager_id, SYSDATE, 'Empleado actualizado');
EXCEPTION
WHEN manager_diferente THEN
INSERT INTO tem_manager (emp_id, manager_new, manager_old, fecha, mensaje)
VALUES (:NEW.employee_id, :NEW.manager_id, :OLD.manager_id, SYSDATE, 'ID del manager actualizado');
END;
/
UPDATE employees SET salary = salary * 1.01 WHERE employee_id = 105;
UPDATE employees SET manager_id = 102 WHERE employee_id = 105;
SELECT * FROM tem_manager;

Disparador simple
CREATE TABLE mensaje (fecha DATE, mensaje_t VARCHAR2(50));
CREATE OR REPLACE TRIGGER t_mensaje
AFTER UPDATE OR INSERT ON employees
DECLARE
v_mensaje VARCHAR2(50);
BEGIN
IF UPDATING THEN
v_mensaje := 'Una fila a sido actualizada en la tabla employees';
END IF;
IF INSERTING THEN
v_mensaje := 'Una fila a sido insertada en la tabla employees';
END IF;
INSERT INTO mensaje (fecha, mensaje_t) VALUES (SYSDATE, v_mensaje);
END;
/
UPDATE employees SET salary = salary * 1.01 WHERE department_id = 60;
INSERT INTO employees VALUES(50, 'Marco', 'Coral', 'UIGV','97211143',
'01/09/02', 'AC_MGR', 9000, .2, 101, 110);
SELECT * FROM mensaje;
DELETE FROM employees WHERE employee_id = 50;

Ejercicios

El gerente de la empresa X desea tener un


reporte cada vez que se actualice la
comisin de un empleado del departamento
con cdigo 60 y cada vez que se contrate a
uno nuevo en el departamento 50, adems
de ello desea saber el nombre del nuevo jefe
de un empleado cuando se modifique este.

Para la siguiente tabla y triggers


identifique su funcionalidad y
connect
sys/systemas;
haga
que funcione
create table
user_log
(
user_id
varchar2(30),
session_id
number(8),
host
varchar2(30),
last_program
varchar2(48),
last_action
varchar2(32),
last_module
varchar2(32),
logon_day
date,
logon_time
varchar2(10),
logoff_day
date,
logoff_time
varchar2(10),
elapsed_minutes
number(8)
);

create or replace trigger


logon_audit_trigger
AFTER LOGON ON XE
BEGIN
insert into user_log values(
user,
sys_context('USERENV','SESSIONID'),
sys_context('USERENV','HOST'),
null,
null,
null,
sysdate,
to_char(sysdate, 'hh24:mi:ss'),
null,
null,
null
);
END;
/

También podría gustarte