+ All Categories
Home > Documents > Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2)...

Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2)...

Date post: 15-Jul-2018
Category:
Upload: lykhuong
View: 239 times
Download: 0 times
Share this document with a friend
38
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
Transcript
Page 1: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

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

Page 2: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Introducción

PL/SQL: lenguaje de programación estructurado en bloques

Bloques: unidad mínima en PL/SQL

Soportan DML y DDL

Anónimos / Con nombre → TRIGGERS

Disparadores (triggers) en Oracle: bloques de código que son implícitamente invocados cuando algo sucede

Triggers VS Procedimientos

Ejecución Implícita: Disparar

No admiten argumentos

Aplicaciones:

Restricciones (Constraints)

Auditorías

Informar de Eventos

DECLARE ▬ optional

BEGIN ▬ required

EXCEPTION ▬ optional

END; required

/

CREATE PROCEDURE Get_emp_rec

(Emp_number IN

Emp_tab.Empno%TYPE) AS

BEGIN

- - - - -

END;

/

CREATE TRIGGER

NombreTrigger

BEFORE INSERT ON StarsIn

DECLARE

…..

END;

/ TRIGGER

PROCEDIMIENTO

Page 3: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Introducción

3 Tipos

DML/DDL (Fila/Sentencia, BEFORE/AFTER)

INSTEAD OF

SYSTEM

Page 4: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Estructura General de un Disparador

CREATE [OR REPLACE] TRIGGER nombre

{BEFORE | AFTER | INSTEAD OF} Temporalidad del Evento

{INSERT | DELETE | UPDATE [OF <atributo>]} ON <tabla>

[WHEN condición] Granularidad[FOR EACH ROW | STATEMENT]

BEGIN

cuerpo del trigger

END;

Evento

Condición

Acción

Page 5: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Temporalidad del Evento: AFTER / BEFORE

BEFORE

Ejecutan la acción asociada antes de que la

sentencia sea ejecutada

Decidir si la acción debe realizarse

Utilizar valores alternativos para la sentenciaCREATE TRIGGER NombreTrigger

BEFORE Insert ON NombreTabla ….

AFTER

Ejecutan la acción asociada después de que

se haya ejecutado la sentenciaCREATE TRIGGER NombreTrigger

AFTER Insert ON NombreTabla ….

Los de tipo BEFORE son

mejores en términos de

rendimiento

Page 6: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Granularidad del Evento:

FOR EACH ROW / STATEMENT

A NIVEL DE FILA:

ROW TRIGGERS

Ejecutan la acción asociada tantas veces como

filas se vean afectadas por la sentencia que lo

dispara

Si ninguna fila se ve afectada, no se disparaCREATE TRIGGER NombreTrigger

BEFORE Insert ON NombreTabla

FOR EACH ROW ….

Utilizar cuando la acción depende de la sentencia

que produjo el evento o de las filas afectadas

Page 7: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Granularidad del Evento:

FOR EACH ROW / STATEMENT

A NIVEL DE SENTENCIA:

STATEMENT TRIGGERS

Ejecutan una única vez la acción asociada,

independientemente del número de filas que se

vean afectadas por la sentenciaCREATE TRIGGER NombreTrigger

BEFORE Insert ON NombreTabla

[STATEMENT]

Utilizar cuando la acción NO depende de la sentencia

que produjo el evento o de las filas afectadas

Comprobaciones de seguridad a cerca del usuario o el

momento concreto

Generar registros de auditoría

Page 8: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Condición

Expresa 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 (< <= > >= = <>).

No se puede especificar una condición para los

disparadores a nivel de sentencia (STATEMENT) ni los

disparadores INSTEAD OF

Debe ser una consulta SQL y no puede contener

subconsultas SELECT * FROM Productos

WHERE PrecioUnidad IN (SELECT PrecioUnidad

FROM DetallePedido

WHERE Descuento = 0 .25)

Page 9: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Orden de Ejecución

Una sentencia SQL puede disparar varios TRIGGERS.

La activación de un trigger puede disparar la activación de otros triggers.

1. Triggers Before (nivel de sentencia)

2. Para cada fila:

1. Trigger Before (a nivel de fila)

2. Ejecuta la Sentencia

3. Triggers After (a nivel de fila)

3. Triggers After (a nivel de Sentencia)

Se compromete o se deshace toda la transacción

El orden de ejecución de disparadores del mismo tipo es indeterminado

Page 10: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Estructura General de un Disparador

CREATE OR REPLACE TRIGGER Control_DocenciaAFTER DELETE ON Profesores

WHEN old.nombre LIKE ‘%Juan%’ FOR EACH ROW

DECLAREvar VARCHAR2(50);

BEGINSELECT a.nombre INTO var FROM Asignaturas a WHERE REF(a) = :NEW.asignatura;

DELETE FROM Asignaturas WHERE nombre = varEND;/

Evento

Condición

Acción

Page 11: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Correlation Identifiers: Valores OLD y NEW

Tipo especial de variable PL/SQL tratada como un registro de tipo

tabla_modificada%ROWTYPE

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)

Condición (WHEN ….) OLD, NEW

En el cuerpo del disparador :OLD, :NEWSINTAXIS

Page 12: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

ROW TRIGGER: ejemplo

Persona

Cod Nombre Edad

C1

C2

C3

C4

C5

María

Pepe

Pepe

Luisa

Pepe

25

40

45

48

22

Persona2

Cod Nombre Edad

C1

C2

C3

C4

C5

María

Pepe

Pepe

Luisa

Pepe

25

40

45

48

22

Cuando se borre en la tabla persona alguna persona que

se llame “pepe” o cuya edad sea mayor de 35 años,

eliminar también dicha persona de la tabla persona2

DELETE FROM persona

WHERE cod in (‘C1’,‘C3’,‘C4’) Borra C3 y C4de persona2

Page 13: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

STATEMENT TRIGGER: ejemplo

Borra 3 tuplas y se emiteun único mensaje

Socio

Cod Nombre Fecha_ant

S1

S2

S3

S4

S5

María

Pepe

Pepe

Luisa

Pepe

......

......

......

......

......

Cuando se borre en la tabla socio emitir un mensaje

indicando que no se pueden borrar socios

DELETE FROM socio

WHERE nombre = ‘Pepe’

Page 14: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Triggers DML

Disparados por sentencias DML:

INSERT, UPDATE o DELETE

Todas las filas o sólo algunas (WHEN)

ISBN GENERO TÍTULO

100-09-89 Novela El Quijote

----- ---- ----

GENERO TOTAL_LIBROS

Novela 50

Infantil 15

CREATE OR REPLACE TRIGGER UpdateEstadisticasGenero

AFTER INSERT OR DELETE OR UPDATE ON Libros

DECLARE

UDDATE Estadisticas SET ….

BEGIN

----------------------

END UpdateEstadisticasGenero;

/

LIBROS ESTADÍSTICAS

Page 15: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

INSERT INTO EmpleadoDpatoVALUES (‘Carlos Gómez', ‘Contabilidad-1’);

ERROR en línea 1:ORA-01779: no se puede modificar una columna que se corresponde con una tabla no reservada por clave

Triggers INSTEAD OF

Sólo sobre VISTAS

DNI NOMBRE DEPARTAMENT

O

11111111 José García CT-1

----- ---- ----

NOMBRE CÓDIGO

Contabilidad - 1 CT-1

Recursos

Humanos

RRHH

EMPLEADO DEPARTAMENTO

CREATE VIEW EmpleadoDpto as

SELECT e.nombre, d.nombre FROM Empleado E, Departamento D

WHERE E.Departamento = D.Codigo;

CREATE OR REPLACE TRIGGER InsertEmepleadoDpto

INSTEAD OF INSERT ON EmpleadoDpto

DECLARE- - --BEGIN

INSERT INTO Empleado VALUES …INSERT INTO Departamento VALUES …

END;

Page 16: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Triggers de Sistema

Disparados por eventos del Sistema o eventos

relacionados con las acciones de los Usuarios

Sistema

Arranque y parada: STARTUP, SHUTDOWN

Transacciones: COMMIT, ROLLBACK

Errores: SERVERERROR

Usuarios

Login / Logoff

Sentencias DDL: CREATE, ALTER,

DROP

CREATE OR REPLACE TRIGGER LogCreations

AFTER CREATE ON SCHEMA

BEGIN

INSERT INTO LogCreates (user_id, object_type,

object_name, object_owner, creation_date)

VALUES (USER, ORA_DCIT_OBJ_TYPE,

ORA_DICT_OBJ_NAME,ORA_DICT_OBJ_OWNER, SYSDATE)

END LogCreations;

/

Page 17: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

BEFORE/AFTER Triggers: ejemplo

CREATE OR REPLACE TRIGGER GenerarAutorID

BEFORE INSERT OR UPDATE ON Autores

FOR EACH ROW

BEGIN

SELECT 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');

Page 18: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Funciones del Cuerpo del Disparador

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 inserción

ELSIF UPDATING[(‘COL1’)]

Acciones asociadas a la modificación

ELSIF UPDATING[(‘COL2’)]

Acciones asociadas a la modificación

END IF;

END ejemplo;

/

Inserting, Deleting, Updating

Page 19: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Elevar excepciones en el cuerpo del Disparador

RAISE_APPLICATION_ ERROR

(nro_error, mensaje); [-20000 y -20999]

CREATE OR REPLACE TRIGGER ejemplo

BEFORE DELETE ON tabla

FOR EACH ROW

BEGIN

IF tabla.columna= valor_no_borrable THEN

RAISE_APPLICATION_ERROR(-20000,‘La fila no se puede borrar’);

END IF;

...

END ejemplo;

Page 20: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Declaración de Variables

nombre CONSTANT NUMBER:=valor;

nombre TIPO;

nombre nombretabla.nombrecolumna%TYPE;

nombre nombretabla%ROWTYPE

CREATE...

BEFORE...

[FOR EACH ROW ...]

DECLARE

Declaración de

variables

BEGIN

Page 21: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

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 ENABLE

ALTER TRIGGER nombre_disparador DISABLE

Page 22: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Consultar información sobre los disparadores

Eliminar un disparador

DROP TRIGGER nombre_disparador;

Ver todos los disparadores y su estado SELECT TRIGGER_NAME, STATUS FROM USER_TRIGGERS;

Ver el cuerpo de un disparadorSELECT TRIGGER_BODY

FROM USER_TRIGGERS

WHERE TRIGGER_NAME='nombre_disparador';

Ver la descripción de un disparadorSELECT DESCRIPTION

FROM USER_TRIGGERS

WHERE TRIGGER_NAME= 'nombre_disparador';

Page 23: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Ejemplo

CREATE TRIGGER Ejemplo

AFTER DELETE ON tabla1

FOR EACH ROW

WHEN ((OLD.nombre=’pepe’) OR (OLD.edad > 35))

BEGIN

DELETE FROM tabla2WHERE tabla2.cod=:OLD.cod;

END Ejemplo;

/

SELECT Trigger_type, Triggering_event, Table_name

FROM USER_TRIGGERS

WHERE Trigger_name = 'Ejemplo';

TYPE TRIGGERING_STATEMENT TABLE_NAME

---------------- ------------------------ ----------

AFTER EACH ROW DELETE tabla1

SELECT Trigger_body FROM USER_TRIGGERS

WHERE Trigger_name = 'Ejemplo';

TRIGGER_BODY

----------------------------------

BEGIN

DELETE FROM tabla2 WHEREtabla2.cod=:OLD.cod;

END Ejemplo;

/

Page 24: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Restricciones: tablas mutantes

Tabla mutante (mutating)

tabla que está siendo modificada por una operación

DML

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 …

Leer o actualizar una tabla mutante que esté en la

propia declaración del disparador

MUTATING TABLE ERROR RUNTIME ERROR

Page 25: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

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 = :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,

‘Datos de profesor incorrectos');

END;

Page 26: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Tablas Mutantes: ejemplo

UPDATE asignaturas

SET DNI = ‘000000000’

WHERE asignaturas_id = ‘BD’;

UPDATE section

*

ERROR at line 1:

ORA-04091: table BD_XX.ASIGNATURAS is mutating,

trigger/function may not see it

ORA-06512: at "BD_XX.TRIGGER_ASIGNATURAS", line 5

ORA-04088: error during execution of trigger

'BD_XX.TRIGGER_ASIGNATURAS'

SELECT COUNT(*)

INTO v_total

FROM asignaturas

WHERE DNI = :NEW.DNI;

Page 27: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Tablas Mutantes: solución

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 (usando los datos almacenados)

La mejor forma de almacenar los valores es utilizar un

paquete (opcionalmente, podríamos utilizar una tabla)

Page 28: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Tablas Mutantes: solución

En el trigger a nivel de fila guardaremos el DNI y el

nombre del profesor

Necesitamos 2 variables globales para que esos datos

estén disponibles más adelante, al ejecutar el trigger a

nivel de fila

Por lo tanto, creamos un paquete que contendrá esas

dos variables

CREATE OR REPLACE PACKAGE pck_profesores AS

v_DNI_profesor profesor.DNI%TYPE;

v_nombre_profesor varchar2(50);

END;

Page 29: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Tablas Mutantes: solución

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||' '||apellidos

INTO pck_profesores.v_nombre_profesor

FROM profesores

WHERE DNI = pck_profesores.DNI;

EXCEPTION

WHEN NO_DATA_FOUND THEN

RAISE_APPLICATION_ERROR(-20001,

‘Datos de Profesor erroneos');

END;

END IF;

END;

En el cuerpo del trigger a nivel de fila usamos las variables del

paquete para guardar el DNI y el nombre del profesor

Page 30: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Tablas Mutantes: solución

TRIGGER a nivel de sentencia

Ahora 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 = 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;

Page 31: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Tablas Mutantes: solución

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'

Page 32: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

TRANSACCIONES y TRIGGERS

Los 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

(timestamp DATE,

operacion VARCHAR2(2000));

Tabla creada.

SQL> CREATE TRIGGER tab1_trig

2 AFTER insert ON tab1

3 BEGIN

4 INSERT INTO log VALUES

(SYSDATE, 'Insert en TAB1');

5 COMMIT;

6 END;

7 /

Trigger created.

SQL> INSERT INTO tab1 VALUES (1);

INSERT INTO tab1 VALUES (1)

*

ERROR at line 1:

ORA-04092: cannot COMMIT in a trigger

ORA-06512: at “BD_XX.TAB1_TRIG", line 3

ORA-04088: error during execution of trigger

‘BD_XX.TAB1_TRIG'

Page 33: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

TRANSACCIONES y TRIGGERS

Se 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 /

Trigger created.

SQL> INSERT INTO tab1 VALUES (1);

1 row created.

Page 34: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

TRANSACCIONES AUTÓNOMAS

Se pueden utilizar autonomous transactions de manera

que el TRIGGER se ejecute en su propia transacción

CREATE OR REPLACE PROCEDURE Grabar_Log(descripcion VARCHAR2)

IS

PRAGMA 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

DECLARE

producto PRECIOS%TYPE;

BEGIN

producto := '100599';

INSERT INTO PRECIOS (CO_PRODUCTO, PRECIO, FX_ALTA) VALUES (producto, 150, SYSDATE);

COMMIT;

EXCEPTION

WHEN OTHERS THEN

Grabar_Log(SQLERRM);

ROLLBACK;

-- 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;

Page 35: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Ejemplos

Dada la siguiente relación:

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, que contiene 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)

Page 36: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Ejemplos

Dadas las siguientes relaciones:

PRODUCTO (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 producto

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

Page 37: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

Ejemplos

Dadas las siguientes relaciones:

PROFESOR (cod_prof)

CLASE (cod_clase, cod_prof)

Se define la siguiente vista:

CREATE VIEW informe_profesores AS

SELECT p.cod_prof, COUNT(c.cod_clase) total_clases

FROM profesor p, clase c

WHERE p.cod_prof = c.cod_prof (+)

GROUP BY p.cod_prof;

Se desea poder invocar sentencias del tipo:

DELETE FROM informe_profesores

WHERE cod_prof = 109;

Page 38: Disparadores en ORACLE en ORACLE Bibliografía Oracle® Database Concepts - 10g Release 2 (10.2) (Octubre 2005) Oracle® Database Application Developer's Guide –Fundamentals 10g

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


Recommended