Disparadores en ORACLE
BibliografíaOracle® Database Concepts ‐ 10g Release 2 (10.2) (Octubre 2005)
Oracle® Database Application Developer's Guide – Fundamentals 10g Release 2 (10.2) (Noviembre 2005)
Óscar Díaz – Universidad del País Vasco (UPV)Bases de Datos Activas
BD ‐ Triggers‐1www.kybele.urjc.esPL/SQL
Introducción
PL/SQL: lenguaje de programación DECLARE ▬ optionalPL/SQL: lenguaje de programación estructurado en bloquesBloques: unidad mínima en PL/SQL
DECLARE optional
BEGIN ▬ required
EXCEPTION ▬ optional
Soportan DML y DDLAnónimos / Con nombre → TRIGGERS
Di d (t i ) O l bl d ódi
END; ▬ required/
Disparadores (triggers) en Oracle: bloques de código que son implícitamente invocados cuando algo sucedeTriggers VS Procedimientos
CREATE TRIGGER NombreTriggerBEFORE INSERT ON StarsInTriggers VS Procedimientos
Ejecución Implícita: DispararNo admiten argumentos
BEFORE INSERT ON StarsInDECLARE
…..END;/ TRIGGER
Aplicaciones:Restricciones (Constraints)
CREATE PROCEDURE Get_emp_rec(Emp_number IN Emp_tab.Empno%TYPE) ASBEGIN
BD ‐ Triggers‐2www.kybele.urjc.esPL/SQL
AuditoríasInformar de Eventos
- - - - -END;/ PROCEDIMIENTO
Introducción
3 Tipos3 TiposDML/DDL (Fila/Sentencia, BEFORE/AFTER)INSTEAD OF
BD ‐ Triggers‐3www.kybele.urjc.esPL/SQL
SYSTEM
Estructura General de un Disparador
CREATE [OR REPLACE] TRIGGER nombre{BEFORE | AFTER | INSTEAD OF} Temporalidad del Evento{INSERT | DELETE | UPDATE [OF <atributo>]} ON <tabla>
EventoEvento
{INSERT | DELETE | UPDATE [OF <atributo>]} ON <tabla>
Granularidad[FOR EACH ROW | STATEMENT][WHEN condición]
CondiciónCondición
BEGINBEGINcuerpo del trigger
END;AcciónAcción
BD ‐ Triggers‐4www.kybele.urjc.esPL/SQL
Temporalidad del Evento: AFTER / BEFOREBEFORE
BEFOREBEFOREEjecutan la acción asociada antes de que la sentencia sea ejecutadasea ejecutadaDecidir si la acción debe realizarseUtili l lt ti l t iUtilizar valores alternativos para la sentencia
CREATE TRIGGER NombreTriggerBEFORE Insert ON NombreTabla ….
Los de tipo BEFORE son mejores en términos de
di i t
AFTEREjecutan la acción asociada después de que se haya
rendimiento
Ejecutan la acción asociada después de que se haya ejecutado la sentencia
CREATE TRIGGER NombreTrigger
BD ‐ Triggers‐5www.kybele.urjc.esPL/SQL
AFTER Insert ON NombreTabla ….
Granularidad del Evento:FOR EACH ROW / STATEMENTFOR EACH ROW / STATEMENT
A NIVEL DE FILA:A NIVEL DE FILA: ROW TRIGGERS
Ejecutan la acción asociada tantas veces como fil f d l i lfilas se vean afectadas por la sentencia que lo dispara
Si ninguna fila se ve afectada, no se disparaCREATE TRIGGER NombreTriggerBEFORE Insert ON NombreTablaBEFORE Insert ON NombreTablaFOR EACH ROW ….
Utilizar cuando la acción depende de la sentencia que
BD ‐ Triggers‐6www.kybele.urjc.esPL/SQL
produjo el evento o de las filas afectadas
Granularidad del Evento:FOR EACH ROW / STATEMENTFOR EACH ROW / STATEMENT
A NIVEL DE SENTENCIA:A NIVEL DE SENTENCIA: STATEMENT TRIGGERS
Ej t ú i l ió i dEjecutan una única vez la acción asociada, independientemente del número de filas que se
f t d l t ivean afectadas por la sentenciaCREATE TRIGGER NombreTriggerBEFORE Insert ON NombreTabla[STATEMENT]
Utilizar cuando la acción NO depende de la sentencia d j l t d l fil f t dque produjo el evento o de las filas afectadas
Comprobaciones de seguridad a cerca del usuario o el momento concreto
BD ‐ Triggers‐7www.kybele.urjc.esPL/SQL
momento concretoGenerar registros de auditoría
Condición
Expresa una condición que debe cumplirse en el momento deExpresa una condición que debe cumplirse en el momento de producirse el evento, para que la acción sea ejecutada.
WHEN persona.nombre = 'pepe' OR persona.edad > 35
Se puede utilizar cualquier combinación de operadores lógicos (AND OR NOT) y relacionales (< <= > >= = <>)(AND, OR, NOT) y relacionales (< <= > >= = <>).
No se puede especificar una condición para los disparadores a nivel de sentencia (STATEMENT) ni los disparadores INSTEAD OF ( ) p
Debe ser una consulta SQL y no puede contener subconsultas
SELECT * FROM ProductosWHERE PrecioUnidad IN (SELECT PrecioUnidad
FROM DetallePedido
BD ‐ Triggers‐8www.kybele.urjc.esPL/SQL
WHERE Descuento = 0 .25)
Orden de Ejecución
Una sentencia SQL puede disparar variosUna sentencia SQL puede disparar varios TRIGGERS.La acti ación de n trigger p ede disparar laLa activación de un trigger puede disparar la activación de otros triggers.
T i B f ( i l d t i )1. Triggers Before (nivel de sentencia)2. Para cada fila:
1. Trigger Before (a nivel de fila)2. Ejecuta la Sentencia3. Triggers After (a nivel de fila)
3. Triggers After (a nivel de Sentencia)3. Triggers After (a nivel de Sentencia)
Se compromete o se deshace toda la transacciónEl orden de ejecución de disparadores del mismo
BD ‐ Triggers‐9www.kybele.urjc.esPL/SQL
El orden de ejecución de disparadores del mismo tipo es indeterminado
Estructura General de un Disparador
CREATE OR REPLACE TRIGGER C t l D iCREATE OR REPLACE TRIGGER Control_DocenciaAFTER DELETE ON Profesores
FOR E CH ROW
EventoEvento
FOR EACH ROWWHEN old.nombre LIKE ‘%Juan%’
CondiciónCondición
DECLAREvar VARCHAR2(50); AcciónAcción( )
BEGINSELECT a.nombre INTO var FROM Asignaturas a WHERE REF(a) = :NEW.asignatura;
DELETE FROM Asignaturas WHERE nombre = varEND;/
BD ‐ Triggers‐10www.kybele.urjc.esPL/SQL
Correlation Identifiers: Valores OLD y NEWNEW
Tipo especial de variable PL/SQL tratada como un registro de tipoTipo especial de variable PL/SQL tratada como un registro de tipo tabla_modificada%ROWTYPE
Con OLD nombre columna referenciamos: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: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 dedifi ió ( )modificación (UPDATE)
Al valor NULL para una operación de borrado (DELETE)
Condición (WHEN ….) OLD, NEWSINTAXIS
BD ‐ Triggers‐11www.kybele.urjc.esPL/SQL
( ) ,En el cuerpo del disparador :OLD, :NEWSINTAXIS
ROW TRIGGER: ejemplo
Cuando se borre en la tabla persona alguna persona queCuando se borre en la tabla persona alguna persona quese llame “pepe” o cuya edad sea mayor de 35 años, eliminar también dicha persona de la tabla persona2
PersonaCod Nombre Edad
Persona2
Cod Nombre EdadCod o b e dadC1C2C3
MaríaPepeP
254045
Cod Nombre EdadC1C2
MaríaPepe
2540
C3C4C5
PepeLuisaPepe
454822
C3C4C5
PepeLuisaPepe
454822p
DELETE FROM persona Borra C3 y C4
BD ‐ Triggers‐12www.kybele.urjc.esPL/SQL
WHERE cod in (‘C1’,‘C3’,‘C4’) y
de persona2
STATEMENT TRIGGER: ejemplo
C d b l t bl i iti j
S i
Cuando se borre en la tabla socio emitir un mensaje indicando que no se pueden borrar socios
Socio
Cod Nombre Fecha_antS1S2S3
MaríaPepePepe
......
......S3S4S5
PepeLuisaPepe
......
......
......
Borra 3 tuplas y se emite ú i j
DELETE FROM socio
BD ‐ Triggers‐13www.kybele.urjc.esPL/SQL
un único mensajeWHERE nombre = ‘Pepe’
Triggers DML
Disparados por sentencias DML:Disparados por sentencias DML: INSERT, UPDATE o DELETE
T d l fil ól l (WHEN)Todas las filas o sólo algunas (WHEN)
ISBN GENERO TÍTULO GENERO TOTAL LIBROS
LIBROS ESTADÍSTICAS
ISBN GENERO TÍTULO100-09-89 Novela El Quijote
----- ---- ----
GENERO TOTAL_LIBROSNovela 50Infantil 15
CREATE OR REPLACE TRIGGER UpdateEstadisticasGenero
AFTER INSERT OR DELETE OR UPDATE ON Libros
DECLARE
………
BEGIN
UDDATE E t di ti SET
BD ‐ Triggers‐14www.kybele.urjc.esPL/SQL
UDDATE Estadisticas SET ….
END UpdateEstadisticasGenero;
/
Triggers INSTEAD OF
Sólo sobre VISTASSólo sobre VISTAS
DNI NOMBRE DEPARTAMENT NOMBRE CÓDIGO
EMPLEADO DEPARTAMENTO
OO
11111111 José García CT-1----- ---- ----
Contabilidad - 1 CT-1Recursos Humanos
RRHH----- ---- ---- Humanos
CREATE VIEW EmpleadoDpto as
SELECT e.nombre, d.nombre FROM Empleado E, Departamento D
WHERE E.Departamento = D.Codigo;
CREATE OR REPLACE TRIGGER InsertEmepleadoDpto
INSERT INTO EmpleadoDpatoVALUES (‘Carlos Gómez', ‘Contabilidad-1’);
ERROR en línea 1:ORA-01779: no se puede modificar una
CREATE OR REPLACE TRIGGER InsertEmepleadoDpto
INSTEAD OF INSERT ON EmpleadoDpto
DECLARE- - --
BEGIN
BD ‐ Triggers‐15www.kybele.urjc.esPL/SQL
ORA-01779: no se puede modificar una columna que se corresponde con una tabla no reservada por clave
INSERT INTO Empleado VALUES …INSERT INTO Departamento VALUES …
END;
Triggers de Sistema
Disparados por eventos del Sistema o eventosDisparados por eventos del Sistema o eventos relacionados con las acciones de los UsuariosSistemaSistema
Arranque y parada: STARTUP, SHUTDOWNTransacciones: COMMIT ROLLBACKTransacciones: COMMIT, ROLLBACKErrores: SERVERERROR
U iUsuariosLogin / Logoff
CREATE OR REPLACE TRIGGER LogCreationsAFTER CREATE ON SCHEMA
BEGININSERT INTO LogCreates (user_id, object_type,object name, object owner, creation date)
Sentencias DDL: CREATE, ALTER, DROP
j _ , j _ , _ )VALUES (USER, ORA_DCIT_OBJ_TYPE,
ORA_DICT_OBJ_NAME,ORA_DICT_OBJ_OWNER, SYSDATE)END LogCreations;/
BD ‐ Triggers‐16www.kybele.urjc.esPL/SQL
DROP
BEFORE/AFTER Triggers: ejemplo
CREATE OR REPLACE TRIGGER GenerarAutorIDBEFORE INSERT OR UPDATE ON AutoresBEFORE INSERT OR UPDATE ON AutoresFOR EACH ROW
BEGINSELECT id_autores INTO :new.ID FROM Tabla_IDs;UPDATE Tabla_IDs SET id_autores = id_autores + 1;
END GenerarAutorID;/
INSERT INTO autores (nombre, apellidos)VALUES ('Lolita', 'Lazarus');
INSERT INTO autores (ID, nombre, apellidos)VALUES ( 7 'Zelda' 'Zoom');
BD ‐ Triggers‐17www.kybele.urjc.esPL/SQL
VALUES (-7, 'Zelda', 'Zoom');
Funciones del Cuerpo del Disparador
Inserting, Deleting, Updating
CREATE OR REPLACE TRIGGER ejemploBEFORE INSERT OR UPDATE OR DELETE ON tabla
Inserting, Deleting, Updating
O S O U O O tab aBEGIN
IF DELETING THENAcciones asociadas al borrado
ELSIF INSERTING THENAcciones asociadas a laAcciones asociadas a la
inserciónELSIF UPDATING[(‘COL1’)]
Acciones asociadas a lamodificaciónmodificación
ELSIF UPDATING[(‘COL2’)]Acciones asociadas a la
modificaciónEND IF;
END j lEND ejemplo;/
BD ‐ Triggers‐18www.kybele.urjc.esPL/SQL
Elevar excepciones en el cuerpo del DisparadorDisparador
RAISE_APPLICATION_ ERROR(nro_error, mensaje); [-20000 y -20999]
CREATE OR REPLACE TRIGGER ejemploBEFORE DELETE ON tablaBEFORE DELETE ON tablaFOR EACH ROWBEGIN
IF tabla columna valor no borrable THENIF tabla.columna= valor_no_borrable THENRAISE_APPLICATION_ERROR(-20000,
‘La fila no se puede borrar’);END IF;END IF;...
END ejemplo;
BD ‐ Triggers‐19www.kybele.urjc.esPL/SQL
Declaración de Variables
CCREATE...BEFORE...[FOR EACH ROW ][FOR EACH ROW ...]DECLARE
Declaración de variablesBEGIN
nombre CONSTANT NUMBER:=valor;nombre TIPO;nombre nombretabla.nombrecolumna%TYPE;
BD ‐ Triggers‐20www.kybele.urjc.esPL/SQL
nombre nombretabla%ROWTYPE
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 están activados al crearse)
Un disparador específico:ALTER TRIGGER nombre disparador ENABLEALTER TRIGGER nombre_disparador ENABLE
ALTER TRIGGER nombre_disparador DISABLE
BD ‐ Triggers‐21www.kybele.urjc.esPL/SQL
Consultar información sobre los disparadoresdisparadores
Eliminar un disparadorEliminar un disparadorDROP TRIGGER nombre_disparador;
Ver todos los disparadores y su estadoVer todos los disparadores y su estadoSELECT TRIGGER_NAME, STATUS FROM USER_TRIGGERS;
Ver el cuerpo de un disparadorVer el cuerpo de un disparadorSELECT TRIGGER_BODYFROM USER_TRIGGERSWHERE TRIGGER_NAME='nombre_disparador';
Ver la descripción de un disparadorSELECT DESCRIPTIONSELECT DESCRIPTION FROM USER_TRIGGERSWHERE TRIGGER_NAME= 'nombre_disparador';
BD ‐ Triggers‐22www.kybele.urjc.esPL/SQL
Ejemplo
CREATE TRIGGER Ejemplo SELECT Trigger_body FROM
AFTER DELETE ON tabla1
FOR EACH ROW
WHEN ((OLD.nombre=’pepe’)
_USER_TRIGGERS
WHERE Trigger_name = 'Ejemplo';
WHEN ((OLD.nombre pepe ) OR (OLD.edad > 35))
BEGIN
DELETE FROM tabla2
TRIGGER_BODY
----------------------------
BEGINWHERE tabla2.cod=:OLD.cod;
END Ejemplo;
/
DELETE FROM tabla2 WHEREtabla2.cod=:OLD.cod;
END Ejemplo;
SELECT Trigger_type, Triggering_event, Table_name
FROM USER_TRIGGERS
/
WHERE Trigger_name = 'Ejemplo';
TYPE TRIGGERING_STATEMENT TABLE_NAME
BD ‐ Triggers‐23www.kybele.urjc.esPL/SQL
---------------- -------------------- ----------
AFTER EACH ROW DELETE tabla1
Restricciones: tablas mutantes
Tabla mutante (mutating)Tabla mutante (mutating)tabla que está siendo modificada por una operación DMLDML
tabla que se verá afectada por los efectos de un DELETE CASCADE debido a la integridad referencial (hasta Oracle8i).
Las órdenes del cuerpo de un disparador (de tipo FOR EACH ROW) no pueden …FOR EACH ROW) no pueden …
Leer o actualizar una tabla mutante que esté en la propia declaración del disparador
BD ‐ Triggers‐24www.kybele.urjc.esPL/SQL
propia declaración del disparador
MUTATING TABLE ERROR RUNTIME ERROR
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á MUTANDOSELECT COUNT(*)INTO v_total FROM asignaturas ASIGNATURAS está MUTANDO
WHERE DNI = :NEW.DNI; -- comprueba si el profesor está sobrecargado
IF v_total >= 10 THEN
SELECT nombre||' '||apellidos INTO v_nombre FROM profesores
WHERE DNI = :NEW.DNI;
RAISE_APPLICATION_ERROR (-20000, ‘El profesor '||
v_nombre||', está sobrecargado');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE APPLICATION ERROR (-20001
BD ‐ Triggers‐25www.kybele.urjc.esPL/SQL
RAISE_APPLICATION_ERROR ( 20001,
‘Datos de profesor incorrectos');
END;
Tablas Mutantes: ejemplo
UPDATE asignaturas
SET DNI = ‘000000000’
WHERE asignaturas id = ‘BD’;WHERE asignaturas_id = BD ;
UPDATE section
*
ERROR at line 1:
SELECT COUNT(*)
INTO v_total
FROM asignaturas
WHERE DNI = :NEW.DNI;ERROR at line 1:
ORA-04091: table BD_XX.ASIGNATURAS is mutating, trigger/function may not see it
O 06512 t " GG S G S" li 5ORA-06512: at "BD_XX.TRIGGER_ASIGNATURAS", line 5
ORA-04088: error during execution of trigger'BD_XX.TRIGGER_ASIGNATURAS'
BD ‐ Triggers‐26www.kybele.urjc.esPL/SQL
Tablas Mutantes: solución
Crear 2 disparadoresCrear 2 disparadores
En el disparador a nivel de fila (for each row) almacenamos los datos que queremos consultardatos que queremos consultar (los que provocan el error de tabla mutante)
E l di d i l d d ( t t t) li lEn el disparador a nivel de orden (statement) realizamos la consulta (usando los datos almacenados)
L j f d l l l iliLa mejor forma de almacenar los valores es utilizar un paquete (opcionalmente, podríamos utilizar una tabla)
BD ‐ Triggers‐27www.kybele.urjc.esPL/SQL
Tablas Mutantes: solución
En el trigger a nivel de fila guardaremos el DNI y el nombre delEn el trigger a nivel de fila guardaremos el DNI y el nombre del profesor
Necesitamos 2 variables globales para que esos datosNecesitamos 2 variables globales para que esos datos estén disponibles más adelante, al ejecutar el triggera nivel de filaa nivel de fila
Por lo tanto, creamos un paquete que contendrá esas dos variablesdos variables
CREATE OR REPLACE PACKAGE pck_profesores AS
v DNI profesor profesor DNI%TYPE;v_DNI_profesor profesor.DNI%TYPE;
v_nombre_profesor varchar2(50);
END;
BD ‐ Triggers‐28www.kybele.urjc.esPL/SQL
Tablas Mutantes: solución
En el cuerpo del trigger a nivel de fila usamos las variables delEn el cuerpo del trigger a nivel de fila usamos las variables del paquete para guardar el DNI y el nombre del profesor
CREATE OR REPLACE TRIGGER trigger_asignaturas
BEFORE INSERT OR UPDATE ON asignaturas
FOR EACH ROW
BEGIN
IF :NEW.DNI IS NOT NULL THEN
BEGIN
pck_profesores.v_DNI_profesor := :NEW.DNI;
SELECT nombre||' '||apellidosSELECT nombre|| ||apellidos
INTO pck_profesores.v_nombre_profesor
FROM profesores
WHERE DNI = pck_profesores.DNI;
EXCEPTION
WHEN NO_DATA_FOUND THENRAISE_APPLICATION_ERROR(-20001,
‘Datos de Profesor erroneos');
BD ‐ Triggers‐29www.kybele.urjc.esPL/SQL
END;
END IF;
END;
Tablas Mutantes: solución
TRIGGER a nivel de sentenciaTRIGGER a nivel de sentenciaAhora realizamos la consulta utilizando las variables globales
CREATE OR REPLACE TRIGGER trigger asignaturas statementgg _ g _
AFTER INSERT OR UPDATE ON asignaturas
DECLARE
v total INTEGER;v_total INTEGER;
BEGIN
SELECT COUNT(*) INTO v_total
FROM asignaturasFROM asignaturas
WHERE DNI = pck_profesores.v_DNI_profesor;
-- comprobamos si el profesor aludido está sobrecargado
IF t t l > 10 THENIF v_total >= 10 THEN
RAISE_APPLICATION_ERROR (-20000, 'El profesor, '||
pck_profesores.v_nombre_profesor || ', está sobrecargado');
BD ‐ Triggers‐30www.kybele.urjc.esPL/SQL
END IF;
END;
Tablas Mutantes: solución
UPDATE asignaturas
SET DNI = ‘000000000’
WHERE asignaturas id = ‘BD’;WHERE asignaturas_id = ‘BD’;
UPDATE asignaturas
*
ERROR at line 1:ORA-20000: El profesor Carlos Romero está sobrecargadoORA-06512: at "BD_XX.TRIGGER_ASIGNATURAS_STATEMENT", line 11ORA-04088: error during execution of trigger'BD XX.TRIGGER ASIGNATURAS STATEMENT'
BD ‐ Triggers‐31www.kybele.urjc.esPL/SQL
_ _ _
TRANSACCIONES y TRIGGERS
Los cambios hechos en un TRIGGER deben ser comprometidos oLos cambios hechos en un TRIGGER deben ser comprometidos o deshechos con la transacción en la que se ejecutan
SQL> CREATE TABLE tab1 (col1 NUMBER);
Tabla creada.
SQL> CREATE TABLE log (ti t DATE
SQL> INSERT INTO tab1 VALUES (1);(timestamp DATE, operacion VARCHAR2(2000));
Tabla creada.
INSERT INTO tab1 VALUES (1)
*
ERROR at line 1:SQL> CREATE TRIGGER tab1_trig
2 AFTER insert ON tab1
3 BEGIN
ERROR at line 1:
ORA-04092: cannot COMMIT in a trigger
ORA-06512: at “BD_XX.TAB1_TRIG", line 3
4 INSERT INTO log VALUES (SYSDATE, 'Insert en TAB1');
5 COMMIT;
6 END
ORA-04088: error during execution of trigger ‘BD_XX.TAB1_TRIG'
BD ‐ Triggers‐32www.kybele.urjc.esPL/SQL
6 END;
7 /
Trigger created.
TRANSACCIONES y TRIGGERS
Se pueden utilizar autonomous transactions de manera que elSe pueden utilizar autonomous transactions de manera que el TRIGGER se ejecute en su propia transacción
SQL> CREATE OR REPLACE TRIGGER tab1_trig
2 AFTER insert ON tab1
3 DECLARE
4 PRAGMA AUTONOMOUS_TRANSACTION;_
5 BEGIN
6 INSERT INTO log VALUES (SYSDATE, 'Insert on TAB1');
7 COMMIT;
8 END;
9 /9 /
Trigger created.
SQL> INSERT INTO tab1 VALUES (1);
BD ‐ Triggers‐33www.kybele.urjc.esPL/SQL
1 row created.
TRANSACCIONES AUTÓNOMAS
Se pueden utilizar autonomous transactions de manera que elSe pueden utilizar autonomous transactions de manera que el TRIGGER se ejecute en su propia transacción
CREATE OR REPLACE PROCEDURE Grabar_Log(descripcion VARCHAR2)ISISPRAGMA AUTONOMOUS_TRANSACTION;BEGIN
INSERT INTO LOG_APLICACION (CO_ERROR, DESCRIPICION, FX_ERROR) VALUES(SQ_ERROR.NEXTVAL, descripcion, SYSDATE);
COMMIT; -- Este commit solo afecta a la transaccion autonoma
END ;
-- utilizamos el procedimiento desde un bloque PL/SQL
DECLAREDECLAREproducto PRECIOS%TYPE;
BEGINproducto := '100599';INSERT INTO PRECIOS (CO_PRODUCTO, PRECIO, FX_ALTA) VALUES (producto, 150,
SYSDATE);COMMIT;
EXCEPTION WHEN OTHERS THEN
Grabar_Log(SQLERRM); ROLLBACK;
BD ‐ Triggers‐34www.kybele.urjc.esPL/SQL
-- Los datos grabados por "Grabar_Log" se escriben en la base de datos a pesar del
-- ROLLBACK, ya que el procedimiento está marcado como transacción autonoma.
END;
Ejemplos
Dada la siguiente relación:
SOCIO (num soc nombre direccion telefono)SOCIO (num_soc, nombre, direccion, telefono)
Se desea mantener la información de los socios aunque estos se den de baja, para lo que se crea una tabla SOCIO_BAJA, quecontiene los datos de socio y la fecha de baja y que se actualizará cada vez que se borre un socio
SOCIO_BAJA (num_soc, nombre, direccion, telefono, fecha_baja)
BD ‐ Triggers‐35www.kybele.urjc.esPL/SQL
Ejemplos
CREATE OR REPLACE TRIGGER borrar_socio
AFTER DELETE ON socio
FOR EACH ROW
BEGIN
INSERT INTO socio_bajaVALUES (:OLD num soc :OLD nombreVALUES (:OLD.num_soc, :OLD.nombre,
:OLD.direccion, :OLD.telefono,SYSDATE);
END borrar_socio;
/
BD ‐ Triggers‐36www.kybele.urjc.esPL/SQL
Ejemplos
Dadas las siguientes relaciones:
PRODUCTO (cod prod descripción proveedorPRODUCTO (cod_prod, descripción, proveedor,unid_vendidas)
ALMACEN (cod_prod_s, stock, stock_min, stock_max) _ _ _ _
1. Se desea mantener actualizado el stock del ALMACEN cada vez que se vendan unidades de un determinado productop
2. Cuando el stock esté por debajo del mínimo lanzar un mensaje de petición de compra. Se indicará el número de unidades a comprar, según el stock actual y el stock maximo
3. Si el stock es menor que el mínimo stock permitido, impedir la venta
BD ‐ Triggers‐37www.kybele.urjc.esPL/SQL
Ejemplos
Dadas las siguientes relaciones:Dadas las siguientes relaciones:
PROFESOR (cod_prof)CLASE ( d l d f)CLASE (cod_clase, cod_prof)
Se define la siguiente vista:
CREATE VIEW informe_profesores ASSELECT p.cod_prof, COUNT(c.cod_clase) total_clasesFROM profesor p clase cFROM profesor p, clase cWHERE p.cod_prof = c.cod_prof (+)GROUP BY p.cod_prof;
Se desea poder invocar sentencias del tipo:Se desea poder invocar sentencias del tipo:
DELETE FROM informe_profesores
BD ‐ Triggers‐41www.kybele.urjc.esPL/SQL
WHERE cod_prof = 109;
Disparadores en ORACLE
BibliografíaOracle® Database Concepts 10g Release 2 (10 2) (Octubre 2005)Oracle® Database Concepts ‐ 10g Release 2 (10.2) (Octubre 2005)
Oracle® Database Application Developer's Guide – Fundamentals 10g Release 2 (10.2) (Noviembre 2005)
Óscar Díaz – Universidad del País Vasco (UPV)Bases de Datos Activas
BD ‐ Triggers‐43www.kybele.urjc.esPL/SQL