1. Bases de Datos
Unidad
El Lenguaje PL/SQL
(Triggers)
2011 Erwin Fischer 2
2. Disparadores (Triggers)
• 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.
2011 Erwin Fischer 3
3. Disparadores (Triggers)
• 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
2011 Erwin Fischer 4
4. ECA-Rules (Event-Condition-Action rules)
• 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.
2011 Erwin Fischer 5
5. Disparadores (Triggers)
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 ...
2011 Erwin Fischer 6
6. Disparadores (Triggers)
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;
2011 Erwin Fischer 7
7. Disparadores (Triggers)
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
2011 Erwin Fischer 8
8. Disparadores (Triggers)
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);
2011 Erwin Fischer 9
9. 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.
2011 Erwin Fischer 10
10. 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.
2011 Erwin Fischer 11
11. Un Trigger con Sequence
• Supongamos que tenemos la
siguiente tabla cliente
Create table Cliente(
idCliente number,
Nombre varchar2(30)
)
• utilizando la secuencia
seqCliente, podemos crear el
siguiente trigger.
2011 Erwin Fischer 12
12. El trigger
Create or Replace trigger trClienteId
Before insert on Cliente
for each row
begin
Select seqCliente.nextval into :new.idCliente
from dual;
end;
2011 Erwin Fischer 13
13. 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
2011 Erwin Fischer 14
14. Consultando Cliente
• Si consultamos la tabla cliente
Select * from Cliente
Vemos que se ha insertado el Idcliente 1000
2011 Erwin Fischer 15
15. 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»
2011 Erwin Fischer 16
16. 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;
2011 Erwin Fischer 17
17. • Ahora tomar en cuenta que el
siguiente insert obtiene el mismo
resultado del trigger, pero sin
activar el trigger.
• Desactivando el trigger
Alter trigger trClienteId disable;
insert into Cliente
Values (seqCliente.nextval, ‘Juan
Perez’)
2011 Erwin Fischer 18
19. Disparadores (Triggers)
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.
2011 Erwin Fischer 20
20. Disparadores (Triggers)
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>';
2011 Erwin Fischer 21
21. Eliminación y desactivación de Triggers
• 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;
2011 Erwin Fischer 22
22. Triggers
Autor
Ejercicio (eliminación en cascada) IdAutor
Cree un trigger que cada vez que se elimine
un autor, elimine todos los registros de
libros asociados a ese autor
Libro
IdLibro
IdAutor
2011 Erwin Fischer 23
23. Triggers
Compra
Ejercicio 1
IdCompra
Fecha
• Para un sistema de Administración de
stock en Bodega, se requiere
implementar la siguiente funcionalidad DetalleCompra
Producto
activa a través de Triggers: IdProducto IdCompra
NombreProducto IdProducto
StockActual Cantidad
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)
2011 Erwin Fischer 24
24. Triggers
Compra
IdCompra
Ejercicio 2 Fecha
• Ampliar el Sistema, agregando registro
de mermas (pérdidas)
DetalleCompra
Producto
IdProducto IdCompra
Cada vez que se registre una merma, NombreProducto
IdProducto
Cantidad
se deberá actualizar en forma
StockActual
automática la existencia en Stock
actual.
Merma
IdMerma
Evento: Merma.Insert Fecha
Condición: - IdProducto
Cantidad
Acción: Producto.Update(StockActual)
2011 Erwin Fischer 25
25. Triggers
Cliente
IdCliente
Ejercicio 3
• Autómata de Giro Bancario
Cada vez que un cliente quiere hacer un LineaCredito Cuenta
IdCuenta
giro, el sistema deberá verificar que su IdLinea
IdCliente
IdCuenta
saldo de cuenta corriente o en su defecto su Saldo Saldo
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 UsoLinea Giro
IdGiro
deberá anular la transacción, en caso IdUso
IdCuenta
IdLinea
contrario, se deberá registrar el nuevo saldo Fecha Fecha
y/o nuevo cupo de línea de crédito y detalle Monto Monto
de la utilización de la línea.
Solución: TAREA, grupal y publicar en su blog
2011 Erwin Fischer 26
26. Investigar o Identificar Triggers
• 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.
2011 Erwin Fischer 27
27. 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
2011 Erwin Fischer 28