Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Belen Disparadores Oracle
Belen Disparadores Oracle
PL/SQL-1
Disparadores en ORACLE
PL/SQL: lenguaje de programacin
estructurado en bloques
Bloques: unidad mnima en PL/SQL
Soportan DML y DDL
Annimos / Con nombre
DECLARE optional
BEGIN required
EXCEPTION optional
END; required
/
Aplicaciones
Restricciones (Constraints)
Auditoras
Informar de eventos
Disparadores en ORACLE
3 Tipos de Disparadores:
DML (Fila/Sentencia, BEFORE/AFTER)
INSTEAD OF (vistas)
SYSTEM
2008 Beln Vela
PL/SQL-3
Disparadores en ORACLE
Estructura General de un Disparador
Evento
Condicin
Accin
PL/SQL-4
Disparadores en ORACLE
Estructura General de un Disparador
Ejemplo
INVENTARIO (num_producto, descripcin, unidades_dispon, punto_pedido, cantidad_pedido)
UPDATE Inventario
SET unidades_dispon=unidades_dispon-3
WHERE num_producto=10456;
SI el nmero de unidades disponibles de ese producto (num_producto=10456) en
el inventario es inferior al punto de pedido
ENTONCES: se genera una nueva orden de pedido
PL/SQL-5
Disparadores en ORACLE
Estructura General de un Disparador
CREATE OR REPLACE TRIGGER Disparador
atributo
tabla
Evento
Condicin
Disparadores en ORACLE
Temporalidad del Evento: AFTER / BEFORE
BEFORE
Ejecutan la accin asociada antes de que la sentencia sea ejecutada
Decidir si la accin debe realizarse o no
Utilizar valores alternativos para la sentencia
CREATE TRIGGER NombreTrigger
BEFORE Insert ON NombreTabla .
AFTER
Ejecutan la accin asociada despus de que se haya ejecutado la
sentencia
CREATE TRIGGER NombreTrigger
AFTER Insert ON NombreTabla .
PL/SQL-7
Disparadores en ORACLE
Granuralidad del Evento:
FOR EACH ROW / STATEMENT
A NIVEL DE FILA: ROW TRIGGERS
Ejecutan la accin asociada tantas veces como filas se vean
afectadas por la sentencia que lo dispara
Si ninguna fila se ve afectada, no se dispara
CREATE TRIGGER NombreTrigger
BEFORE UPDATE ON NombreTabla
FOR EACH ROW
[WHEN ].
A NIVEL DE SENTENCIA: STATEMENT TRIGGERS
Ejecutan una nica vez la accin asociada, independientemente del
nmero de filas que se vean afectadas por la sentencia (incluso si
no hay filas afectadas).
CREATE TRIGGER NombreTrigger
BEFORE INSERT ON NombreTabla
2008 Beln Vela
[STATEMENT] . . .
opcin por defecto
PL/SQL-8
Disparadores en ORACLE
Ejemplo: A NIVEL DE FILA (ROW TRIGGER)
Cuando
Cuandose
seborre
borreen
enlalatabla
tablaPersona
Personaalguna
algunapersona
personaque
que
se
sellame
llamepepe
pepeoocuya
cuyaedad
edadsea
seamayor
mayorde
de35
35aos,
aos,
eliminar
eliminartambin
tambindicha
dichapersona
personade
delalatabla
tablaPersona2.
Persona2.
Persona
Cod Nombre Edad
C1
C2
C3
C4
C5
Mara
Pepe
Pepe
Luisa
Pepe
25
40
45
48
22
DELETE
DELETE FROM
FROM Persona
Persona
WHERE
cod
in
WHERE cod in (C1,C3,C4)
(C1,C3,C4)
Persona2
Cod
C1
C2
C3
C4
C5
Nombre Edad
Mara
Pepe
Pepe
Luisa
Pepe
25
40
45
48
22
Borra C3 y C4
de Persona2
PL/SQL-9
Disparadores en ORACLE
Ejemplo: A NIVEL DE SENTENCIA (STATEMENT)
Cuando
Cuandose
seborre
borreen
enlalatabla
tablaSocio
Socioemitir
emitirun
un
mensaje
mensajeindicando
indicandoque
queno
nose
sedeberan
deberanborrar
borrarsocios
socios
Socio
Cod Nombre Fecha_ant
S1
S2
S3
S4
S5
Mara
Pepe
Pepe
Luisa
Pepe
DELETE
DELETE FROM
FROM socio
socio
WHERE
nombre
WHERE nombre == Pepe
Pepe
2008 Beln Vela
......
......
......
......
......
Disparadores en ORACLE
Orden de Ejecucin
1.
2.
3.
PL/SQL-11
Disparadores en ORACLE
Condicin
Expresa una condicin que debe cumplirse en el momento
de producirse el evento, para que la accin sea ejecutada.
Se evala para cada fila.
WHEN old.nombre = pepe OR old.edad > 35
PL/SQL-12
Disparadores en ORACLE
Condicin (WHEN .)
En el cuerpo del disparador
OLD, NEW
:OLD, :NEW
PL/SQL-13
Disparadores en ORACLE
Ejemplo: A NIVEL DE FILA (ROW TRIGGER)
Cuando
Cuandose
seborre
borreen
enlalatabla
tablaPersona
Personaalguna
algunapersona
personaque
que
se
sellame
llamepepe
pepeoocuya
cuyaedad
edadsea
seamayor
mayorde
de35
35aos,
aos,
eliminar
eliminartambin
tambindicha
dichapersona
personade
delalatabla
tablaPersona2.
Persona2.
Persona
Cod Nombre Edad
C1
C2
C3
C4
C5
Mara
Pepe
Pepe
Luisa
Pepe
25
40
45
48
22
DELETE
DELETE FROM
FROM Persona
Persona
WHERE
cod
in
WHERE cod in (C1,C3,C4)
(C1,C3,C4)
Persona2
Cod
C1
C2
C3
C4
C5
Nombre Edad
Mara
Pepe
Pepe
Luisa
Pepe
25
40
45
48
22
Borra C3 y C4
de Persona2
PL/SQL-14
Disparadores en ORACLE
Ejemplo: A NIVEL DE FILA (ROW TRIGGER)
Nombre
NULL
Edad
NULL
OLD
PL/SQL-15
Disparadores en ORACLE
Triggers DML
Disparados por sentencias DML (de varios tipos):
INSERT or UPDATE or DELETE
Todas las filas o slo algunas (WHEN)
LIBROS
ESTADSTICAS
ISBN
GNERO
TTULO
GNERO
TOTAL_LIBROS
100-09-89
Novela
El Quijote
Novela
50
-----
----
----
Infantil
15
PL/SQL-16
Disparadores en ORACLE
Funciones del Cuerpo del Disparador
Inserting, Deleting, Updating
CREATE OR REPLACE TRIGGER Ejemplo
BEFORE INSERT OR UPDATE OR DELETE ON tabla
BEGIN
IF DELETING THEN
Acciones asociadas al borrado
ELSIF INSERTING THEN
Acciones asociadas a la insercin
ELSIF UPDATING(COL1)
Acciones asociadas a la modificacin
ELSIF UPDATING(COL2)
Acciones asociadas a la modificacin
END IF;
END Ejemplo;
/
2008 Beln Vela
PL/SQL-17
Disparadores en ORACLE
Triggers INSTEAD OF
Slo sobre VISTAS
EMPLEADO
DEPARTAMENTO
DNI
NOMBRE
DEPARTAMENTO
NOMBRE
CDIGO
11111111
Jos Garca
CT-1
Contabilidad - 1
CT-1
-----
----
----
Recursos Humanos
RRHH
Disparadores en ORACLE
Elevar excepciones en el cuerpo del Disparador
RAISE_APPLICATION_ ERROR (nmero_error, mensaje);
Nmero error en el rango: [-20000 y -20999]
CREATE OR REPLACE TRIGGER Ejemplo
BEFORE DELETE ON tabla
FOR EACH ROW
BEGIN
IF :OLD.columna= valor_no_borrable THEN
RAISE_APPLICATION_ERROR(-20000,
La fila no se puede borrar);
END IF;
...
END ejemplo;
/
2008 Beln Vela
PL/SQL-19
Disparadores en ORACLE
Triggers de Sistema
Disparados por eventos del Sistema o eventos relacionados con
las acciones de los Usuarios
Sistema
CREATE OR REPLACE TRIGGER LogCreations
Arranque y parada de BD
AFTER CREATE ON SCHEMA
BEGIN
Transacciones
INSERT INTO LogCreates (user_id, object_type,
object_name, object_owner, creation_date)
Errores
VALUES (USER, ORA_DCIT_OBJ_TYPE,
ORA_DICT_OBJ_NAME,ORA_DICT_OBJ_OWNER,
Usuarios
SYSDATE)
END LogCreations;
Login / Logoff
/
Sentencias DDL: CREATE, ALTER, DROP,
PL/SQL-20
Disparadores en ORACLE
Declaracin de Variables
CREATE...
BEFORE | AFTER ...
[FOR EACH ROW ...]
DECLARE
Declaracin de variables
BEGIN
nombre
nombre
nombre
nombre
2008 Beln Vela
CONSTANT NUMBER:=valor;
TIPO;
nombretabla.nombrecolumna%TYPE;
nombretabla%ROWTYPE
PL/SQL-21
Disparadores en ORACLE
Activar/Desactivar Disparadores
Todos los disparadores asociados a una tabla:
ALTER TABLE nombre_tabla ENABLE ALL TRIGGERS;
ALTER TABLE nombre_tabla DISABLE ALL TRIGGERS;
(Por defecto: Todos estn Activados al crearse)
Un disparador especfico:
ALTER TRIGGER nombre_disparador ENABLE;
ALTER TRIGGER nombre_disparador DISABLE;
Borrar un Disparador
DROP TRIGGER nombre_disparador;
PL/SQL-22
Disparadores en ORACLE
Consultar informacin sobre los disparadores
Ver todos los disparadores y su estado
SELECT TRIGGER_NAME , STATUS FROM USER_TRIGGERS;
Ver el cuerpo de un disparador
SELECT TRIGGER_BODY FROM USER_TRIGGERS WHERE
TRIGGER_NAME=nombre_disparador;
Ver la descripcin de un disparador
SELECT DESCRIPTION FROM USER_TRIGGERS WHERE
TRIGGER_NAME= nombre_disparador;
PL/SQL-23
Disparadores en ORACLE
Ejemplo
CREATE OR REPLACE TRIGGER Reorder
TRIGGER_BODY
DECLARE
-------------------------------------------DECLARE
x NUMBER;
x NUMBER;
BEGIN
BEGIN
FROM Pending_orders
IF x = 0 THEN
END;
END;
TYPE
TRIGGERING_STATEMENT
TABLE_NAME
----------------
--------------------------
------------
UPDATE
INVENTORY
PL/SQL-24
Disparadores en ORACLE
Restricciones: Tablas Mutantes
Tabla mutante (mutating)
tabla que est siendo modificada por una operacin DML
tabla que se ver afectada por los efectos de un DELETE
CASCADE debido a la integridad referencial (hasta
Oracle8i).
PL/SQL-25
Disparadores en ORACLE
Estructura General de un Disparador
Ejemplo
Asignaturas (nombre_A, descripcin, DNI_Profesor)
PL/SQL-26
Disparadores en ORACLE
Tablas Mutantes: ejemplo
CREATE OR REPLACE TRIGGER trigger_asignaturas
BEFORE INSERT OR UPDATE ON Asignaturas
FOR EACH ROW
DECLARE
v_total
NUMBER;
v_nombre VARCHAR2(30);
BEGIN
SELECT COUNT(*)
INTO v_total
FROM Asignaturas -- ASIGNATURAS est MUTANDO
WHERE DNI_Profesor = :NEW.DNI_Profesor;
-- comprueba si el profesor est sobrecargado
IF v_total >= 10 THEN
SELECT nombre||' '||apellidos
INTO v_nombre
FROM Profesores
WHERE DNI = :NEW.DNI_Profesor;
RAISE_APPLICATION_ERROR (-20000, El profesor '||v_nombre||', est sobrecargado');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR (-20001,Datos de profesor incorrectos');
END;
2008 Beln
Vela
/
PL/SQL-27
Disparadores en ORACLE
Tablas Mutantes: ejemplo
UPDATE Asignaturas
SET DNI_Profesor = 000000000
WHERE nombre_A = BD;
UPDATE section
SELECT COUNT(*)
INTO v_total
*
ERROR at line 1:
FROM Asignaturas
WHERE DNI_Profesor = :NEW.DNI_Profesor;
PL/SQL-28
Disparadores en ORACLE
Tablas Mutantes: solucin
Crear 2 disparadores
En el disparador a nivel de fila (for each row)
almacenamos los datos que queremos consultar
(los que provocan el error de tabla mutante)
En el disparador a nivel de orden (statement)
realizamos la consulta (sobre los datos almacenados
en lugar de sobre la tabla)
La mejor forma de almacenar los valores es utilizar
un paquete (opcionalmente, podramos utilizar una
tabla)
PL/SQL-29
Disparadores en ORACLE
Tablas Mutantes: solucin
PL/SQL-30
Disparadores en ORACLE
Tablas Mutantes: solucin
CREATE OR REPLACE TRIGGER trigger_asignaturas
BEFORE INSERT OR UPDATE ON Asignaturas
FOR EACH ROW
BEGIN
IF :NEW.DNI_Profesor IS NOT NULL THEN
Buscamos el
nombre del
profesor y lo
metemos en
la variable
del paquete
Asignamos el
DNI a la variable
del paquete
BEGIN
pck_profesores.v_DNI_profesor := :NEW.DNI_Profesor;
SELECT nombre||' '||apellidos
INTO pck_profesores.v_nombre_profesor
FROM Profesores
WHERE DNI = pck_profesores.DNI;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20001,
Este profesor no existe');
END;
END IF;
END;
PL/SQL-31
Disparadores en ORACLE
Tablas Mutantes: solucin
TRIGGER a nivel de sentencia
realizamos la consulta utilizando las variables globales
CREATE OR REPLACE TRIGGER trigger_asignaturas_statement
AFTER INSERT OR UPDATE ON Asignaturas
DECLARE
v_total INTEGER;
BEGIN
SELECT COUNT(*) INTO v_total
FROM Asignaturas
WHERE DNI_Profesor = pck_profesores.v_DNI_profesor;
-- comprobamos si el profesor aludido est sobrecargado
IF v_total >= 10 THEN
RAISE_APPLICATION_ERROR (-20000, 'El profesor '||
pck_profesores.v_nombre_profesor || ' est sobrecargado');
END IF;
END;
2008 Beln Vela
PL/SQL-32
Disparadores en ORACLE
Tablas Mutantes: solucin
UPDATE asignaturas
SET DNI = 000000000
WHERE asignaturas_id = BD;
UPDATE asignaturas
*
ERROR at line 1:
ORA-20000: El profesor Carlos Romero est sobrecargado
ORA-06512: at "BD_XX.TRIGGER_ASIGNATURAS_STATEMENT", line 11
ORA-04088: error during execution of trigger
'BD_XX.TRIGGER_ASIGNATURAS_STATEMENT'
PL/SQL-33
Disparadores en ORACLE
Tablas Mutantes: solucin cuando hay ms de una
fila afectada por la instruccin
PL/SQL-34
Disparadores en ORACLE
Tablas Mutantes: solucin cuando afecta a ms de 1 fila
CREATE OR REPLACE TRIGGER trigger_asignaturas BEFORE INSERT OR UPDATE ON Asignaturas
FOR EACH ROW
DECLARE
Insertamos el
Indice binary_integer;
DNI y Nombre
BEGIN
en la variable
IF :NEW.DNI_Profesor IS NOT NULL THEN
tabla
BEGIN
Indice:= pck.profesores.tabla_profesores.COUNT+1;
pck_profesores.tabla_profesores(Indice).DNI := :NEW.DNI_Profesor;
SELECT nombre||' '||apellidos
INTO pck_profesores.tabla_profesores(Indice).v_nombre_profesor
FROM Profesores
WHERE DNI = :NEW.DNI_Profesor;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20001,'Este profesor no existe');
END;
END IF;
2008 Beln Vela
END;
PL/SQL-35
Disparadores en ORACLE
Tablas Mutantes: solucin cuando afecta a ms de 1 fila
TRIGGER a nivel de sentencia:se consulta recorriendo la variable tabla
CREATE TRIGGER trigger_asignaturas_statement AFTER INSERT OR UPDATE ON Asignaturas
DECLARE
v_total INTEGER;
Vaciamos tabla temporal
para que sea usado por
Indice binary_integer;
la siguiente ejecucin del
nombre_prof varchar(50);
disparador
BEGIN
FOR Indice in 1..pck_profesores.tabla_profesores.count loop
SELECT COUNT(*) INTO v_total
FROM Asignaturas WHERE DNI_Profesor =
pck_profesores.tabla_profesores(Indice).v_DNI_profesor;
-- comprobamos si el profesor aludido est sobrecargado
IF v_total >= 10 THEN
nombre_prof:=pck_profesores.tabla_profesores(Indice).v_nombre_profesor;
pck_profesores.tabla_profesores.delete; -- vaciar tabla
RAISE_APPLICATION_ERROR (-20000, Profesor '||nombre_prof|| 'sobrecargado');
END IF;
END LOOP;
pck_profesores.tabla_profesores.delete; -- vaciar tabla
2008 Beln Vela
PL/SQL-36
END;
Bibliografa
Bibliografa Bsica
Abbey, Corey y Abramson. ORACLE8i: Gua de Aprendizaje
(versiones 7.x, 8 y 8i). McGraw-Hill.
Urman S. ORACLE 8: Programacin PL/SQL. McGraw-Hill.
Urman S., Hardman, R., y McLaughlin, M. ORACLE DATABASE 10g.
PL/SQL Programming. Oracle Press, 2004.
Bibliografa Complementaria
Elmasri, R. y Navathe, S. B. Fundamentos de Sistemas de Bases de
Datos. Tercera Edicin. Addison-Wesley Iberoamericana, 2000.
PL/SQL-37
PL/SQL-38