Sei sulla pagina 1di 9

Desencadenantes

Los disparadores son procedimientos que se ejecutan cuando se produce un suceso de base de datos (una operacin ( INSERT, UPDATE o DELETE) en una tabla especfica. El acto de ejecutar un trigger se conoce como disparo o desencadenante Los disparadores pueden emplearse para muchas cosas diferentes, incluyendo: El mantenimiento de restricciones de integridad complejas, que no sean posibles con las restricciones declarativas definidas en el momento de crear la tabla. La auditora de la informacin contenida en una tabla, registrando los cambios realizados y la identidad del que los llev a cabo. El aviso automtico a otros programas de que hay que llevar a cabo una determinada accin, cuando se realiza un cambio en una tabla. Sintaxis CREATE [OR REPLACE] TRIGGER <nombre> {BEFORE|AFTER} {DELETE|INSERT|UPDATE [OF col1, col2, . . ., colN] [OR {DELETE|INSERT|UPDATE [OF col1, col2, . . ., colN]. . .]} ON table [REFERENCING OLD AS oldname, NEW as newname] [FOR EACH ROW [WHEN (condition)]] [declare] [begin] pl/sql_block [begin;] Eliminacin y deshabilitacin de los disparadores La sintaxis de la orden que elimina un disparador es: DROP TRIGGER nombre_disparador; La sintaxis de la orden que deshabilita un disparador es : ALTER TRIGGER nombre_disparador [DISABLE | ENABLE]

EJEMPLOS Procedimiento que permite eliminar un item de la tabla detalle create or replace procedure eliminaitem ( num in char, cod in char) as begin delete from detalle where num_fact=num and cod_prod=cod; COMMIT; end;

select num_fact, cod_prod from detalle where num_fact=000944; Crear un trigger que permita actualizar el stock del producto cuando se elimina un detalle de venta create or replace trigger eliminardeta after delete on detalle FOR EACH ROW begin update producto set stock=stock + :old.cant where cod_prod=:old.cod_prod; end; SELECT * FROM PRODUCTO WHERE COD_PROD=P0012;

Ejercicio:

Crear un procedimiento llamado insertaritem en la tabla detalle, considerar la existencia del numero de la factura (verificar que el producto no se repita en su detalle) Sol: 1.- verificar que el numero de la factura exista Select count(*) from detalle where num_fact=000943; 2.- verificar que el producto no se repita Select count(*) from detalle where num_fact=000943 and cod_prod=P0006;

Select precio, precio_cos from producto where cod_prod=P0006;

create or replace procedure INSERTARITEM ( num in char, cod in char, CAN in number ) as NOEXISTE NUMBER; PRE NUMBER; COS NUMBER; begin Select count(*) INTO NOEXISTE from detalle where num_fact=NUM AND cod_prod= COD; IF NOEXISTE = 0 THEN Select precio, precio_cos from INTO PRE, COS producto where cod_prod=COD;

INSERT INTO DETALLE VALUES (NUM,COD, PRE,COS,CAN); End if COMMIT; end; -----------------------------------------------------------------------create or replace trigger ingredeta after insert on detalle FOR EACH ROW begin update producto set stock=stock - :new.cant where cod_prod=:new.cod_prod; end;

1. Definicin de trigger Los disparadores son procedimientos que se ejecutan cuando se produce un suceso de base de datos (una operacin DML: INSERT, UPDATE o DELETE) en una tabla especfica. El acto de ejecutar un disparador se conoce como disparo. 2. Uso de los triggers Los disparadores pueden emplearse para muchas cosas diferentes, incluyendo: El mantenimiento de restricciones de integridad complejas, que no sean posibles con las restricciones declarativas definidas en el momento de crear la tabla. La auditora de la informacin contenida en una tabla, registrando los cambios realizados y la identidad del que los llev a cabo. El aviso automtico a otros programas de que hay que llevar a cabo una determinada accin, cuando se realiza un cambio en una tabla. 3. Sintaxis general de trigger Lo presentado en este apartado se ha extrado desde [2]. La sintaxis general para crear un disparador es: CREATE [OR REPLACE] TRIGGER nombre_disparador { BEFORE | AFTER ? suceso_disparo ON referencia_tabla [FOR EACH ROW [ WHEN condicin_disparo ]] cuerpo_disparador, donde nombre_disparador es el nombre del disparador, suceso_disparo especifica cundo se activa el disparador, referencia_tabla es la tabla para la cual se define el disparador y cuerpo_disparador es el cdigo principal del disparador. Antes se evala la condicin_disparo incluida en la clusula WHEN, si es que est presente. El cuerpo del disparador se ejecuta slo cuando dicha condicin se evala como verdadera. 4. Componentes de un disparador Los componentes de un disparador son el nombre, el suceso de disparo y el cuerpo. La clusula WHEN es opcional. 5.1 Nombres de disparadores El espacio de nombres para los disparadores es diferente del de otros subprogramas. El espacio de nombres es el conjunto de identificadores vlidos que pueden emplearse como nombres de un objeto. Los disparadores existen en un espacio de nombres separado del de los procedimientos, paquetes y tablas, por lo que un disparador puede tener el mismo nombre que una tabla o procedimiento. Sin embargo dentro de un mismo esquema deben tener nombres diferentes entre s. 5.2 Tipos de disparadores El suceso de disparo determina el tipo de disparador. Los disparadores pueden definirse para las operaciones INSERT, UPDATE o DELETE, y pueden dispararse antes o despus de la operacin. Finalmente, el nivel de los disparadores puede ser la fila o la orden. La Figura 1 muestra los tipos de disparadores: Categora Orden Temporizacin Nivel Valores INSERT, DELETE, UPDATE BEFORE o AFTER Fila u orden Comentarios Define qu tipo de orden DML provoca la activacin del disparador. Define si el disparador se activa antes o despus de que se ejecute la orden (disparador previo o posterior). Los disparadores con nivel de fila se activan una vez por cada fila afectada por la orden que provoc el disparo. Los disparadores con nivel de orden se activan slo una

vez, antes o despus de la orden. Los disparadores con nivel de fila se identifican por la clusula FOR EACH ROW en la definicin del disparador. Figura 1. Tipos de disparadores [2] Disparadores de sustitucin Oracle 8 proporciona un tipo adicional de disparador. Los disparadores de sustitucin ( INSTEAD OF ) pero tienen una serie de restricciones [3]: INSTEAD OF es una clusula vlida solo para vistas; no se puede especificar un disparador INSTEAD OF en una tabla. Si una vista tiene un disparador INSTEAD OF, cualquier vista creada sobre sta debe tener a su vez un disparador INSTEAD OF. Cuando definimos disparadores INSTEAD OF para columnas LOB, podemos leer tanto el seudo-registro :OLD como el seudo-registro :NEW, pero no se puede modificar sus valores.

5.3 Restricciones de los disparadores El cuerpo de un disparador es un bloque PL/SQL. Cualquier orden que sea legal en un bloque PL/SQL, es legal en el cuerpo de un disparador, con las siguientes restricciones: 1. Un disparador no puede emitir ninguna orden de control de transacciones: COMMIT, ROLLBACK o SAVEPOINT. El disparador se activa como parte de la ejecucin de la orden que provoc el disparo, y forma parte de la misma transaccin que dicha orden. Cuando la orden que provoca el disparo es confirmada o cancelada, se confirma o cancela tambin el trabajo realizado por el disparador. 2. Por razones idnticas, ningn procedimiento o funcin llamado por el disparador puede emitir rdenes de control de transacciones. 3. El cuerpo del disparador no puede contener ninguna declaracin de variables LONG o LONG RAW. 4. Existen restricciones acerca de a qu tablas puede acceder el cuerpo de un disparador. Dependiendo del tipo de disparador y de las restricciones que afecten a las tablas.

5. Eliminacin y deshabilitacin de los disparadores La sintaxis de la orden que elimina un disparador es [4]: DROP TRIGGER nombre_disparador; donde nombre_disparador es el nombre del disparador que se desea eliminar. Esta orden elimina el disparador de forma permanente del diccionario de datos. La sintaxis de la orden que deshabilita un disparador es [4]: ALTER TRIGGER nombre_disparador [DISABLE | ENABLE] donde nombre_disparador es el nombre del disparador. Todos los disparadores estn habilitados en el momento de su creacin. Cuando se deshabilita un disparador continua existiendo en el diccionario de datos. Tambin se puede habilitar o deshabilitar todos los disparadores de una tabla determinada, utilizando la orden ALTER TABLE con la clusula ENABLE ALL TRIGGERS o DISABLE ALL TRIGGERS. 6. Orden de activacin de los disparadores Lo presentado en este apartado se ha extrado desde [2]. Los disparadores se activan al ejecutarse la orden DML. El algoritmo de ejecucin de una orden DML es el siguiente: 1. Ejecutar, si existe, el disparador de tipo BEFORE (disparador previo) con nivel de orden. 2. Para cada fila a la que afecte la orden: a. Ejecutar, si existe, el disparador de tipo BEFORE con nivel de fila. b. Ejecutar la propia orden. c. Ejecutar, si existe, el disparador de tipo AFTER (disparador posterior) con nivel de fila. 3. Ejecutar, si existe, el disparador de tipo AFTER con nivel de orden.

7. Utilizacin de :old y :new en los disparadores con nivel de fila Un disparador con nivel de fila se ejecuta una vez por cada fila procesada por la orden que provoca el disparo. Dentro del disparador puede accederse a la fila que est siendo actualmente procesada utilizando, para ello, dos seudo-registros, :old y :new. La Figura 2 muestra este concepto: Orden de disparo INSERT UPDATE DELETE

:old No definido; todos los campos toman valor NULL. Valores originales de la fila, antes de la actualizacin. Valores, antes del borrado de la fila.

:new Valores que sern insertados cuando se complete la orden. Nuevos valores que sern escritos cuando se complete la orden. No definidos; todos los campos toman el valor NULL.

Figura 2. :old y :new [2]

El tipo de estos seudo-registros es : tabla_disparo%ROWTYPE; donde tabla_disparo es la tabla sobre la que se ha definido el disparador. Los registros :new y :old son slo vlidos dentro de los disparadores con nivel de fila. Si se intenta Hacer referencia a cualquiera de los dos dentro de un disparador con nivel de orden, se obtendr un error de compilacin. Puesto que un disparador con nivel de orden se ejecuta una sola vez, incluso si la orden procesa varias filas, entonces :old y :new no tienen ningn sentido ya que no se sabe a que fila se estn refiriendo. 8. La clusula WHEN Lo presentado en este apartado se ha extrado desde [2]. La clusula WHEN slo es vlida para los disparadores con nivel de fila. Si est presente, el cuerpo del disparador slo se ejecutar para las filas que cumplan la condicin especificada en la clusula. La clusula WHEN tiene la forma: WHEN condicin donde condicin es una expresin booleana que ser evaluada para cada fila. Se puede hacer tambin referencia a los registros :new y :old dentro de la condicin, pero en ese caso no se utilizan los dos puntos.

9. Utilizacin de predicados de los disparadores: INSERTING, UPDATING y DELETING Dentro de un disparador en el que se disparan distintos tipos de rdenes DML (INSERT, UPDATE y DELETE), hay tres funciones booleanas que pueden emplearse para determinar de qu operacin se trata. Estos predicados son INSERTING, UPDATING y DELETING. Su comportamiento es el siguiente: La Figura 3 muestra el comportamiento de INSERTING, UPDATING y DELETING Predicado INSERTING UPDATING DELETING Comportamiento TRUE si la orden de disparo es INSERT; FALSE en otro caso. TRUE si la orden de disparo es UPDATE; FALSE en otro caso. TRUE si la orden de disparo es DELETE; FALSE en otro caso.

Figura 3. INSERTING, UPDATING y DELETING [2]

10. Ejemplo Un ejemplo de su uso es proporcionar una facilidad de auditora donde se realiza automticamente un registro de actividades siempre que se cambia una fila de una tabla. Sin los disparadores de bases de datos esta funcion sera implementada en los programas de seccion de entrada (front-end) que realizan el cambio en la base de datos; sin embargo alguien que se pase por alto el cdigo de los programas de seccin de entrada (utilizando SQL*Plus, por ejemplo) no pasara por las comprobaciones y el procesamiento definidos. Supngase que tenemos una tabla llamada SAL (en la que almacenamos los salarios de los empleados de la empresa) y resulta necesario conocer cundo esta siendo accedida la tabla y el tipo de operacin que se realiza. El ejemplo que presentamos a continuacin contiene un paquete de muestra que rastrea esta informacin registrando la hora y la accion ejecutada (UPDATE, DELETE, o INSERT) en la tabla SAL. Mediante una variable global, STAT.ROWCNT, inicializada a cero por el trigger BEFORE e incrementada cada vez que un disparador con nivel de fila es ejecutado, tenemos la informacion estadstica que necesitamos salvar en el disparador AFTER. DROP TABLE stat_tab; CREATE TABLE stat_tab(utype CHAR(8), rowcnt INTEGER, uhour INTEGER); CREATE OR REPLACE PACKAGE stat IS rowcnt INTEGER; END;

CREATE TRIGGER bt BEFORE UPDATE OR DELETE OR INSERT ON sal BEGIN stat.rowcnt := 0; END;

CREATE TRIGGER rt BEFORE UPDATE OR DELETE OR INSERT ON sal FOR EACH ROW BEGIN stat.rowcnt := stat.rowcnt + 1; END;

CREATE TRIGGER at AFTER UPDATE OR DELETE OR INSERT ON sal DECLARE typ CHAR(8); hour NUMBER; BEGIN IF updating THEN typ := 'update'; END IF; IF deleting THEN typ := 'delete'; END IF; IF inserting THEN typ := 'insert'; END IF; hour := TRUNC((SYSDATE - TRUNC(SYSDATE)) * 24); UPDATE stat_tab SET rowcnt = rowcnt + stat.rowcnt WHERE utype = typ AND uhour = hour; IF SQL%ROWCOUNT = 0 THEN INSERT INTO stat_tab VALUES (typ, stat.rowcnt, hour); END IF; EXCEPTION WHEN dup_val_on_index THEN UPDATE stat_tab SET rowcnt = rowcnt + stat.rowcnt WHERE utype = typ AND uhour = hour; END;

Potrebbero piacerti anche