disparadores en oracle - kybele.etsii.urjc.es · oracle® database application developer's...

39
Disparadores en ORACLE Bibliografía 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 Triggers1 www.kybele.urjc.es PL/SQL

Upload: builiem

Post on 22-Oct-2018

240 views

Category:

Documents


0 download

TRANSCRIPT

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