Vous êtes sur la page 1sur 14

Disparadores (Triggers)

MSI Perla Ivonne Cordero de los Ríos

Disparadores (Triggers)
 Es una orden que el sistema ejecuta
de manera automática como efecto
secundario de la modificación de la
base de datos. Para diseñar el
mecanismo hay que cumplir con dos
requisitos:
 Especificar las condiciones en las que se
va ejecutar el disparador.
 Especificar las acciones que se van a
realizar cuando se ejecute el disparador

1
Datos generales

 Una vez que se almacena un


disparador en la base de datos, el
sistema de BD asume la
responsabilidad de ejecutarlo cada
vez que ocurra un evento
especificado y se satisfaga la
condición correspondiente.
 Son Procedimientos PLSQL o Java

Necesidad de los disparadores


 Los disparadores son mecanismos
útiles para alertar a los usuarios o
para realizar de manera automática
ciertas tareas cuando se cumplen
determinadas condiciones.
 EJEMPLO.
 No dejar saldos de cuenta negativos

2
Disparadores en SQL
 Cada Sistema de BD implementó su
propia sintaxis para los disparadores
conduciendo a incompatibilidades.

Tipos

 UPDATE
 BEFORE (ANTES)
 INSERT
 AFTER (DESPUÉS)
 DELETE
 INSTEAD (EN VEZ
DE)

3
TRIGGER
 Sintaxis

CREATE [OR REPLACE] TRIGGER nombre_disparador


{BEFORE |AFTER |INSTEAD OF suceso_disparo
[clausula_referencia]
[WHEN condicion_disparador]
[FOR EACH ROW]
Cuerpo_disparador;

SINTAXIS GENERAL DE UN
DISPARADOR EN SQL:2003

 WHEN condición
 OLD
 NEW
 Si están el en cuerpo del disparador se
referencian como :OLD ó :NEW

4
SINTAXIS GENERAL DE UN
DISPARADOR EN SQL:2003
 Con OLD.nombre_columna referenciamos:
 Al valor que tenía la columna antes del cambio debido a una
modificación (UPDATE)
 Al valor de una columna antes de una operación de borrado
sobre la
misma (DELETE)
 Al valor NULL para operaciones de inserción (INSERT)
 Con NEW.nombre_columna referenciamos:
 Al valor de una nueva columna después de una operación de
inserción (INSERT)
 Al valor de una columna después de modificarla mediante
una sentencia de modificación (UPDATE)
 Al valor NULL para una operación de borrado (DELETE)

Ejemplo
CREATE TRIGGER Ejemplo-fila
AFTER DELETE OF codigo ON tabla1
FOR EACH ROW
WHEN ((OLD.nombre=’pepe’) OR (OLD.edad >
35))
BEGIN
DELETE FROM tabla2 WHERE
tabla2.cod=:OLD.cod;
END Ejemplo-columna;
/

5
INSTEAD OF
 INSTEAD OF. Sólo para vistas
CREATE VIEW vista AS
SELECT edificio, sum(numero_asientos)
FROM Habitaciones GROUP BY edificio;
 Es ilegal hace una operación de borrado
directamente en la vista:
 DELETE FROM vista WHERE edificio=’edificio
7’;

Disparadores en sustitución
CREATE TRIGGER borra_en_vista
INSTEAD OF DELETE ON vista
FOR EACH ROW
BEGIN
DELETE FROM habitaciones
WHERE edificio = :OLD.edificio;
END borra_en_vista;

6
Activar y desactivar
disparadores
 Todos los disparadores asociados a una tabla:
 ALTER TABLE nombre_tabla ENABLE ALL
TRIGGERS
 ALTER TABLE nombre_tabla DISABLE ALL
TRIGGERS
 • Un disparador específico:
 ALTER TRIGGER nombre_disparador ENABLE
 ALTER TRIGGER nombre_disparador DISABLE

7
Otras funciones
 Eliminar un disparador
 DROP TRIGGER nombre_disparador;
 Ver todos los disparadores y su estado
 SELECT TRIGGER_NAME , STATUS FROM
USER_TRIGGERS;

Otras funciones
 Ver el cuerpo de un disparador
 SELECT TRIGGER_BODY FROM
USER_TRIGGERS WHERE
TRIGGER_NAME=‘nombre_disparador’;
 Ver la descripción de un disparador
 – SELECT DESCRIPTION FROM
USER_TRIGGERS WHERE
TRIGGER_NAME= ‘nombre_disparador’;

8
Ejemplo
CREATE OR REPLACE TRIGGER checar_salario
BEFORE INSERT OR UPDATE ON empleado
FOR EACH ROW
WHEN (new.trabajo<>’presidente’)
DECLARE
v_salariomin empleado.salario%TYPE;
v_salariomax empleado.salario%TYPE;
BEGIN
SELECT MAX(salario), MIN(salario) FROM empleado
INTO v_salariomin, v_salariomax
FROM empleado
WHERE trabajo=:new.trabajo;
IF :new.salario<v_salariomin OR :new.salario> v_salariomax THEN
RAISE_APPLICATION_ERROR(-20001, ‘Sueldo fuera de rango’);
END IF;
END chequear_salario;
/
UPDATE empleado SET salario=1500 WHERE
nom_emp=‘Cortecero’;

Aplicar Select para verificar la


información …
SQL> select * from departamentos;

IDDEPARTAMENTO DESCRIPCION
-------------- --------------------
1 contabilidad
2 sistemas ¿Qué pasa si deseo
Borrar el departamento
SQL> select * from empleados; 2 (Sistemas)?

IDEMPLEADO NOMBRE AP AM ¿Se puede borrar?


---------- -------------------- -------------------- --------------------
1 Juan Garcia Perez
2 Xochilt Etchechurry Quilaqueo ¿Si se borra el registro
Que ocurre con emp_dep?
SQL> select * from emp_dep;

IDEMPLEADO IDDEPARTAMENTO FECHAINGR FECHATERM


---------- -------------- --------- ---------
1 1 25-MAY-06
2 2 25-MAY-06

9
Con los triggers …

 Te permite validar … para evitar


inconsistencias en la información …

Ejemplo práctico
create trigger tD_Departamentos after DELETE on Departamentos for each row
declare numrows INTEGER;
begin
-- Verifica cuantos registros del idDepartamento se tienen en la tabla Emp_Dep y
-- lo almacenas en la variable numrows.

select count(*) into numrows


from Emp_Dep
where Emp_Dep.idDepartamento = :old.idDepartamento;
-- old.idDepartamento, es el departamento que quieres borrar
if (numrows > 0)
-- si el numrows es mayor que cero, significa que se encontró un registro del ---
-- departamento
-- que deseas borrar.
then
-- raise_application_error, crea un error por parte del usuario
raise_application_error(
-20001, 'No puedes borrar departamentos por que en la tabla Emp_Dep
existe.' );
end if;
end;

10
Resultados …
SQL> delete departamentos where iddepartamento=2;
delete departamentos where iddepartamento=2
*
ERROR at line 1:
ORA-20001: No puedes borrar departamentos por que
en la tabla Emp_Dep existe.
ORA-06512: at "PCORDERO.TD_DEPARTAMENTOS",
line 14
ORA-04088: error during execution of trigger
'PCORDERO.TD_DEPARTAMENTOS'

Crear un trigger para no permitir insertar un


número del departamento negativo.
create or replace trigger DepNeg AFTER INSERT on Departamentos
for each row
begin
-- Si el nuevo valor que se va insertar es negativo mostrar error
if (:new.idDepartamento < 1) then
-- raise_application_error, crea un error por parte del usuario
raise_application_error(
-20001, 'No puedes insertar un número de departamento
negativo');
end if;
end;
/

11
Resultados …
SQL> insert into departamentos values (3, 'Finanzas');

1 row created.

SQL> select * from departamentos;

IDDEPARTAMENTO DESCRIPCION
-------------- --------------------
1 contabilidad
2 sistemas
3 Finanzas

SQL> insert into departamentos values (-5,'Contabilidad');


insert into departamentos values (-5,'Contabilidad')
*
ERROR at line 1:
ORA-20001: No puedes insertar un número de departamento negativo
ORA-06512: at "PCORDERO.DEPNEG", line 7
ORA-04088: error during execution of trigger 'PCORDERO.DEPNEG‘

EJEMPLO
CREATE OR REPLACE TRIGGER existe_dep_par
BEFORE UPDATE
ON departamentos_par
FOR EACH ROW
DECLARE
dep departamentos_par.dep_id%TYPE;
existedep BOOLEAN := TRUE;
BEGIN
BEGIN
SELECT dep_id INTO dep
FROM departamentos_par d
WHERE d.dep_id = :new.dep_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
existedep := false;
END;
IF existedep THEN
RAISE_APPLICATION_ERROR(-20120,'NO Existe Departamento');
END IF;
END;

12
EJEMPLO
USANDO EL DEPARTAMENTO NO ELIMINAR

CREATE OR REPLACE TRIGGER existe_dep_par


BEFORE DELETE
ON departamentos_par
FOR EACH ROW
DECLARE
num NUMBER;
BEGIN
SELECT COUNT(*) INTO num
FROM empleados_par e
WHERE e.dep_id = :old.dep_id;

IF num > 0 THEN


RAISE_APPLICATION_ERROR(-20111,'Departamento Usado No se Puede Eliminar');
END IF;
END;

EJEMPLO
Escribir un Trigger que almacene en una tabla Bitácora, el usuario, fecha y el tipo de operación realizada sobre la tabla de Jobs
(I=Insert, U=Update, D=Delete)

SQL> create table bitacora(usuario varchar2(20), fecha date, operacion char);

Table created.

SQL> create or replace trigger bit_op


2 after insert or update or delete
3 on jobs
4 declare
5 op char;
6 begin
7 if inserting then
8 op:='I';
9 end if;
10 if updating then
11 op:='U';
12 end if;
13 if deleting then
14 op:='D';
15 end if;
16 insert into bitacora values(user,sysdate,op);
17 End;
Trigger created.

SQL> update jobs set min_salary = 10000 where job_id = 'AD_PRES';


1 row updated.
SQL> select * from bitacora;
USUARIO FECHA O
-------------------- --------- -
PONCHOR 19-SEP-06 U

13
Referencias
 Copyright @Oracle Corporation, 1998
All rights reserved. ORACLE
 Modelos Avanzados de Bases de

Datos Curso 2004/2005

14

Vous aimerez peut-être aussi