Professional Documents
Culture Documents
Bibliografa 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 Daz Universidad del Pas Vasco (UPV) Bases de Datos Activas
Introduccin
PL/SQL: lenguaje de programacin estructurado en bloques Bloques: unidad mnima en PL/SQL
Soportan DML y DDL Annimos / Con nombre TRIGGERS
DECLARE optional BEGIN required EXCEPTION optional END; / required
Disparadores (triggers) en Oracle: bloques de cdigo que son implcitamente invocados cuando algo sucede CREATE TRIGGER Triggers VS Procedimientos NombreTrigger
Ejecucin Implcita: Disparar No admiten argumentos
BEFORE INSERT ON StarsIn DECLARE .. END; TRIGGER / CREATE PROCEDURE Get_emp_rec (Emp_number IN Emp_tab.Empno%TYPE) AS BEGIN - - - - END; /
Aplicaciones:
Restricciones (Constraints) Auditoras Informar de Eventos
PROCEDIMIENTO
Introduccin
3 Tipos
DML/DDL (Fila/Sentencia, BEFORE/AFTER) INSTEAD OF SYSTEM
CREATE [OR REPLACE] TRIGGER nombre {BEFORE | AFTER | INSTEAD OF} Temporalidad del Evento {INSERT | DELETE | UPDATE [OF <atributo>]} ON <tabla>
Evento
Condicin
BEGIN
Accin
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 Insert ON NombreTabla FOR EACH ROW .
Utilizar cuando la accin depende de la sentencia que produjo el evento o de las filas afectadas
Granularidad del Evento: FOR EACH ROW / STATEMENT 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
CREATE TRIGGER NombreTrigger BEFORE Insert ON NombreTabla [STATEMENT]
Utilizar cuando la accin 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 auditora
Condicin
Expresa una condicin que debe cumplirse en el momento de producirse el evento, para que la accin sea ejecutada.
WHEN persona.nombre = 'pepe' OR persona.edad > 35
Se puede utilizar cualquier combinacin de operadores lgicos (AND, OR, NOT) y relacionales (< <= > >= = <>). No se puede especificar una condicin 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)
Orden de Ejecucin Una sentencia SQL puede disparar varios TRIGGERS. La activacin de un trigger puede disparar la activacin de otros triggers.
1. 2. Triggers Before (nivel de sentencia) Para cada fila: 1. Trigger Before (a nivel de fila) 2. Ejecuta la Sentencia 3. Triggers After (a nivel de fila) Triggers After (a nivel de Sentencia)
3.
Se compromete o se deshace toda la transaccin El orden de ejecucin de disparadores del mismo tipo es indeterminado
Evento Condicin
DECLARE var VARCHAR2(50); BEGIN SELECT a.nombre INTO var FROM Asignaturas a WHERE REF(a) = :NEW.asignatura; DELETE FROM Asignaturas WHERE nombre = var END; /
Accin
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
Socio
Cod Nombre Fecha_ant
S1 S2 S3 S4 S5 Mara Pepe Pepe Luisa Pepe ...... ...... ...... ...... ......
Triggers DML Disparados por sentencias DML: INSERT, UPDATE o DELETE Todas las filas o slo algunas (WHEN)
LIBROS
ESTADSTICAS
TOTAL_LIBROS 50 15
BEGIN
---------------------END UpdateEstadisticasGenero;
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 EmpleadoDpato VALUES (Carlos Gmez', Contabilidad-1); INSTEAD OF INSERT ON EmpleadoDpto DECLARE - - -BEGIN INSERT INTO Empleado VALUES INSERT INTO Departamento VALUES
ERROR en lnea 1: ORA-01779: no se puede modificar una columna que se corresponde con una tabla no reservada por clave
END;
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; /
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');
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;
Declaracin de Variables
CREATE... BEFORE... [FOR EACH ROW ...] DECLARE Declaracin de variables BEGIN
Un disparador especfico:
ALTER TRIGGER nombre_disparador ENABLE
ALTER TRIGGER nombre_disparador DISABLE
Ejemplo
CREATE TRIGGER Ejemplo AFTER DELETE ON tabla1 FOR EACH ROW WHEN ((OLD.nombre=pepe) OR (OLD.edad > 35)) BEGIN DELETE FROM tabla2 WHERE tabla2.cod=:OLD.cod; BEGIN
SELECT Trigger_body FROM USER_TRIGGERS WHERE Trigger_name = 'Ejemplo';
TRIGGER_BODY
----------------------------------
END Ejemplo;
/
SELECT Trigger_type, Triggering_event, Table_name FROM USER_TRIGGERS WHERE Trigger_name = 'Ejemplo'; TYPE ---------------AFTER EACH ROW TRIGGERING_STATEMENT -----------------------DELETE TABLE_NAME ---------tabla1
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 declaracin del disparador MUTATING TABLE ERROR RUNTIME ERROR
v_total
BEGIN
NUMBER;
v_nombre VARCHAR2(30);
UPDATE section
SELECT COUNT(*)
INTO v_total
FROM asignaturas WHERE DNI = :NEW.DNI;
*
ERROR at line 1:
v_DNI_profesor profesor.DNI%TYPE;
v_nombre_profesor varchar2(50);
END;
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;
END IF;
END;
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'
TRANSACCIONES y TRIGGERS
Los cambios hechos en un TRIGGER deben ser comprometidos o deshechos con la transaccin en la que se ejecutan
SQL> CREATE TABLE tab1 (col1 NUMBER); Tabla creada.
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'
3
4 5 6 7
BEGIN
INSERT INTO log VALUES (SYSDATE, 'Insert en TAB1'); COMMIT; END; /
Trigger created.
TRANSACCIONES y TRIGGERS
Se pueden utilizar autonomous transactions de manera que el TRIGGER se ejecute en su propia transaccin
SQL> CREATE OR REPLACE TRIGGER tab1_trig 2 3 4 5 AFTER insert ON tab1 DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN
6
7 8 9
Trigger created.
1 row created.
TRANSACCIONES AUTNOMAS
Se pueden utilizar autonomous transactions de manera que el TRIGGER se ejecute en su propia transaccin
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 transaccin autonoma.
END;
Se desea mantener la informacin 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)
3.
Se desea mantener actualizado el stock del ALMACEN cada vez que se vendan unidades de un determinado producto Cuando el stock est por debajo del mnimo lanzar un mensaje de peticin de compra. Se indicar el nmero de unidades a comprar, segn el stock actual y el stock maximo Si el stock es menor que el mnimo stock permitido, impedir la venta
Ejemplos
Dadas las siguientes relaciones:
PROFESOR (cod_prof) CLASE (cod_clase, cod_prof)
Disparadores en ORACLE
Bibliografa 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 Daz Universidad del Pas Vasco (UPV) Bases de Datos Activas