Post on 25-May-2015
22011 Erwin Fischer
Bases de Datos
Unidad
El Lenguaje PL/SQL(Triggers)
32011 Erwin Fischer
• Un triggers define una acción que la BD debe realizar
cuando tenga lugar un determinado suceso en la
aplicación
• Un trigger, al igual que una función o procedimiento es
un objeto de la base de datos.
• En la práctica es un procedimiento almacenado, pero de
uso interno al DBMS, por lo cual no usa parámetros.
• Se asocian a tablas y operaciones de modificación
básicas sobre ellas (Insert, Delete, Update).
• Se ejecuta automáticamente cuando alguna de estas
operaciones básicas sucede, antes que la modificación
se haga permanente en la base de datos.
• Puede incorporar cualquier tipo o agrupación de
sentencias SQL, al igual que un procedimiento
almacenado.
Disparadores (Triggers)
42011 Erwin Fischer
• Los triggers pueden utilizarse para imponer ciertas restricciones
de integridad referencial, para imponer reglas de negocios
complejas, o para auditar los cambios en los datos
• Los triggers se basan en el modelo ECA (Event-Condition-Action,
evento-condición-acción)
• El Evento que dispara la regla especificada, en Oracle puede ser:
• Una instrucción INSERT, UPDATE, DELETE
• Una instrucción CREATE, ALTER o DROP
• Un arranque de la BD o detención de la instancia
• Un inicio o fin de sesión por parte del usuario
• Un mensaje de Error
• La Condición que determina si la acción que debe
ejecutarse. Es opcional, pero si se especifica, la acción
se ejecutará si la condición se evalúa como verdadera
• La Acción que hay que llevar a cabo. Este bloque
contiene el código y las instrucciones SQL que se
ejecutan cuando se produce el evento y la condición es
verdadera
Disparadores (Triggers)
52011 Erwin Fischer
• Una vez que un set de reglas ha sido definidas el
ADBMS monitorea los eventos relevantes. Un evento
relevante es aquel que tiene definida alguna regla.
• Cada vez que el ADBMS detecta la ocurrencia de un
evento relevante, notifica al componente encargado de
la ejecución de la regla asociada. Esta notificación se
denomina “event signalling” o señalización de eventos.
• En consecuencia, todas las reglas definidas para
responder a dicho evento se “disparan” (trigger), y
deben ser ejecutadas.
• La ejecución de reglas incorpora la evaluación de
condiciones, y si dichas condiciones satisfacen, se
ejecuta la acción.
ECA-Rules (Event-Condition-Action rules)
62011 Erwin Fischer
Aquí se presenta la sintaxis para crear un disparador en Oracle (que se
diferencia levemente de la sintaxis estándar de SQL):
CREATE [OR REPLACE] TRIGGER <trigger_name>
{BEFORE|AFTER} {INSERT|DELETE|UPDATE} ON <table_name>
[REFERENCING [NEW AS <new_row_name>] [OLD AS <old_row_name>]]
[FOR EACH ROW [WHEN (<trigger_condition>)]]
<trigger_body>
Se puede usar solamente TRIGGERS BEFORE o AFTER para tablas INSTEAD
OF triggers son utilizados para vistas (típicamente para vistas de
actualización)
Se puede especificar hasta tres disparadores de eventos usando la palabra
clave OR.
... INSERT ON R ...
... INSERT OR DELETE OR UPDATE ON R ...
... UPDATE OF A, B OR INSERT ON R ...
Disparadores (Triggers)
72011 Erwin Fischer
Se muestra la sintaxis de Oracle para crear triggers a través de un
ejemplo basado en las dos tablas siguientes:
CREATE TABLE T4 (a INTEGER, b CHAR(10));
CREATE TABLE T5 (c CHAR(10), d INTEGER);
CREATE TRIGGER trig1
AFTER INSERT ON T4
REFERENCING NEW AS newRow
FOR EACH ROW
WHEN (newRow.a <= 10)
BEGIN
INSERT INTO T5 VALUES(:newRow.b, :newRow.a);
END trig1;
Disparadores (Triggers)
82011 Erwin Fischer
CREATE TRIGGER TopeDeManejoPropiedadEmpleado
BEFORE INSERT OR UPDATE ON Propiedad
FOR EACH ROW
DECLARE
vcontP NUMBER;
BEGIN
SELECT COUNT(*) INTO vcontP
FROM Propiedad
WHERE numEmpleado = new.numEmpleado;
IF vcontP = 100
Raise_application_error(-2000, („Empleado „||
new.numEmpleado|| „ ya administra 100 propiedades‟);
END IF
END
Disparadores (Triggers)
92011 Erwin Fischer
create table Person (age int);
CREATE TRIGGER PersonCheckAge AFTER INSERT OR UPDATE OF age ON Person FOR EACH ROW BEGIN
IF (:new.age < 0) THEN RAISE_APPLICATION_ERROR(-20000, 'no negative age
allowed'); END IF;
END; . RUN;
Si intentamos ejecutar la inserción:
insert into Person values (-3);
Disparadores (Triggers)
102011 Erwin Fischer
Create Sequence
• Es un objeto de base de datos
• Se utiliza para crear una secuencia, para generar enteros únicos.
• Por ejemplo se puede utilizar secuencias para generar automáticamente valores de clave principal.
112011 Erwin Fischer
Create Sequence un ejemplo
CREATE SEQUENCE seqCliente
START WITH 1000
INCREMENT BY 1
NOCACHE
NOCYCLE;
La primera referencia a seqCliente.nextval retorna 1000. la segunda retorna 1001.
Cada consulta posterior devolverá un valor mayor en 1 que la referencia anterior.
122011 Erwin Fischer
Un Trigger con Sequence
• Supongamos que tenemos la siguiente tabla clienteCreate table Cliente(
idCliente number,
Nombre varchar2(30)
)
• utilizando la secuencia seqCliente, podemos crear el siguiente trigger.
132011 Erwin Fischer
El trigger
Create or Replace trigger trClienteId
Before insert on Cliente
for each row
begin
Select seqCliente.nextval into :new.idCliente
from dual;
end;
142011 Erwin Fischer
Insertando registros
• Luego para insertar un registro en la tabla cliente, bastaría hacer el siguiente insert:insert into Cliente (nombre)
Values (‘Juan Perez’)
–Observe que no hemos insertado el atributo idCliente
152011 Erwin Fischer
Consultando Cliente
• Si consultamos la tabla cliente
Select * from Cliente
Vemos que se ha insertado el Idcliente 1000
162011 Erwin Fischer
Predicados
• Dentro de un trigger se pueden utilizar predicados, que retornan valores booleanos, para identificar la acción que esta realizando
• Inserting: Devuelve verdadero si la instrucción que disparó el trigger fue un «Insert»
• Updating: Devuelve verdadero si la instrucción que disparó el trigger fue un «Update»
• Deleting: Devuelve verdadero si la instrucción que disparó el trigger fue un «Delete»
172011 Erwin Fischer
Trigger con predicado
Create or Replace trigger trClienteId
Before insert on Cliente
for each row
begin
if inserting then
Select seqCliente.nextval into :new.idCliente
from dual;
else
:new.idCliente = 0;
end if;
End trClienteId;
182011 Erwin Fischer
• Ahora tomar en cuenta que el siguiente insert obtiene el mismo resultado del trigger, pero sin activar el trigger.
• Desactivando el triggerAlter trigger trClienteId disable;
insert into Cliente
Values (seqCliente.nextval, ‘Juan
Perez’)
192011 Erwin Fischer
Consultando cliente nuevamente
• Select * from Cliente
INSERT into Cliente Values (seqCliente.nextval, ‘Juan Perez’)
202011 Erwin Fischer
Exhibiendo errores de la definición del disparador
Como para los procedimientos PL/SQL si obtiene un mensaje de
error en la creación del triggers, puede ver el error con:
show errors trigger <trigger_name>;
Alternativamente se puede usar,
SHO ERR (short for SHOW ERRORS)
Notar que los números de líneas reportados no son exactos.
Disparadores (Triggers)
212011 Erwin Fischer
Para ver una lista de los triggers definidos usar:
select trigger_name from user_triggers;
Para mas detalles de un trigger en particular:
select trigger_type, triggering_event, table_name, referencing_names, trigger_body
from user_triggers where trigger_name = '<trigger_name>';
Disparadores (Triggers)
222011 Erwin Fischer
• Para eliminar un trigger se utiliza:
Drop trigger «nombre_trigger»;
• Para desactivar un trigger se utiliza
Alter trigger «nombre_trigger» disable;
• Para activar un trigger se utiliza
Alter trigger «nombre_trigger» enable;
• Para activar todos los trigger de una tabla se utiliza
Alter table «nombre_tabla» enable all triggers;
Eliminación y desactivación de Triggers
232011 Erwin Fischer
Ejercicio (eliminación en cascada)
Cree un trigger que cada vez que se elimine
un autor, elimine todos los registros de
libros asociados a ese autor
Triggers
Autor
IdAutor
Libro
IdLibro
IdAutor
242011 Erwin Fischer
Ejercicio 1
• Para un sistema de Administración de
stock en Bodega, se requiere
implementar la siguiente funcionalidad
activa a través de Triggers:
Cada vez que se agregue un registro de
detalle de compra, se deberá actualizar
en forma automática la existencia en
Stock actual.
Evento: DetalleCompra.Insert
Condición: -
Acción: Producto.Update(StockActual)
Triggers
Compra
IdCompra
Fecha
DetalleCompra
IdCompra
IdProducto
Cantidad
Producto
IdProducto
NombreProducto
StockActual
252011 Erwin Fischer
Ejercicio 2
• Ampliar el Sistema, agregando registro
de mermas (pérdidas)
Cada vez que se registre una merma,
se deberá actualizar en forma
automática la existencia en Stock
actual.
Evento: Merma.Insert
Condición: -
Acción: Producto.Update(StockActual)
Triggers
Compra
IdCompra
Fecha
DetalleCompra
IdCompra
IdProducto
Cantidad
Producto
IdProducto
NombreProducto
StockActual
Merma
IdMerma
Fecha
IdProducto
Cantidad
262011 Erwin Fischer
Ejercicio 3
• Autómata de Giro Bancario
Cada vez que un cliente quiere hacer un
giro, el sistema deberá verificar que su
saldo de cuenta corriente o en su defecto su
cupo de línea de crédito sea suficiente para
cubrir la operación.
Si la suma del saldo disponible en la cuenta
y el saldo de la línea no logra cubrir, se
deberá anular la transacción, en caso
contrario, se deberá registrar el nuevo saldo
y/o nuevo cupo de línea de crédito y detalle
de la utilización de la línea.
Triggers
Cliente
IdCliente
Cuenta
IdCuenta
IdCliente
Saldo
Giro
IdGiro
IdCuenta
Fecha
Monto
LineaCredito
IdLinea
IdCuenta
Saldo
UsoLinea
IdUso
IdLinea
Fecha
Monto
Solución: TAREA, grupal y publicar en su blog
272011 Erwin Fischer
• Con su grupo de trabajo, identifique las situaciones en
que seria deseable algún tipo de funcionalidad activa o
autonomía.
• Para cada uno de ellos defina el evento, condición y
acción.
• Publique en su blog, las situaciones y el o los triggers
asociados que resuelven dicha situación.
Investigar o Identificar Triggers
282011 Erwin Fischer
Unidad - PL/SQL - Triggers
• Si tiene una sugerencia, comentario u observación para mejorar este material, agradecería me envíe un mail a erfisch@gmail.com.
Atentamente
Profesor Erwin Fischer