Trigger (Disparadores) Exposiciòn Final Lunes Taller de Base
Trigger (Disparadores) Exposiciòn Final Lunes Taller de Base
Trigger (Disparadores) Exposiciòn Final Lunes Taller de Base
TIPOS DE TRIGGER
Si existe, se ejecuta el disparador de tipo BEFORE (disparador previo) con nivel de orden.
Para cada fila a la que afecte la orden:
Se ejecuta si existe, el disparador de tipo BEFORE con nivel de fila.
Se ejecuta la propia orden.
Se ejecuta si existe, el disparador de tipo AFTER (disparador posterior) con nivel de fila.
Se ejecuta, si existe, el disparador de tipo AFTER con nivel de orden.
RESTRICCIONES
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:
Por las mismas razones, ningún procedure o función llamado por el disparador puede emitir
órdenes de control de transacciones.
Un evento
Un momento
Un tipo
El evento se refiere a la operación que se efectúa sobre la tabla (INSERT, DELETE o UPDATE).
Ejemplo. Sea:
Use Ejemplo
GO
CREATE TRIGGER NuevoPedido
ON Pedidos
FOR INSERT
AS
UPDATE RepVentas
SET VENTAS =VENTAS + INSERTED.IMPORTE
FROM REPVENTAS INNER JOIN INSERTED
ON REPVENTAS.NUM_EMPL = INSERTED.REP
UPDATE PRODUCTOS
SET EXISTENCIAS = EXISTENCIAS - INSERTED.CANT
FROM PRODUCTOS INNER JOIN INSERTED
ON PRODUCTOS.ID_FAB = INSERTED.FAB
AND PRODUCTOS.ID_PRODUCTO = INSERTED.PRODUCTO
GO
Ejemplo
Para comprobar la ejecución de este Desencadenador ejecute las siguientes
sentencias:
Antes de ejecutar un INSERT de prueba, mostraremos la información con respecto
a un producto
Select * From Productos Where Id_Fab= 'ACI' AND Id_Producto='41001'
GO
Ejemplo
Los triggers se crean con la instrucción "create trigger" seguido del nombre del disparador. Si se agrega
"or replace" al momento de crearlo y ya existe un trigger con el mismo nombre, tal disparador será
borrado y vuelto a crear, de esta manera se puede modificar.
En caso que una sola sentencia "update" modifique varios registros en la tabla asociada, el trigger se disparará
una sola vez; si queremos que se active una vez por cada registro afectado, debemos indicarlo con "for each
row".
La siguiente es la sintaxis para crear un trigger de actualización a nivel de fila, se dispare una vez por cada fila
modificada sobre la tabla especificada:
La siguiente es la sintaxis para crear un trigger de inserción que se dispare cada vez que
se ejecute una sentencia "insert" sobre la tabla especificada, es decir, cada vez que se
intenten ingresar datos en la tabla:
Analizamos la sintaxis:
Luego de la instrucción "create trigger" se coloca el nombre del disparador. Si se agrega "or
replace" al momento de crearlo y ya existe un trigger con el mismo nombre, tal disparador será
borrado y vuelto a crear.
- "MOMENTO" indica cuando se disparará el trigger en relación al evento, puede se BEFORE
(antes) o AFTER (después). Se especifica el evento que causa que el trigger se dispare, en este caso
"insert", ya que el trigger se activará cada vez que se ejecute la sentencia "insert" sobre la tabla
especificada luego de "on".
- Es un trigger a nivel de sentencia, es decir, se dispara una sola vez por cada sentencia "insert",
aunque la sentencia ingrese varios registros. Es el valor por defecto si no se especifica.
- Finalmente se coloca el cuerpo del trigger dentro del bloque "begin.. end".
Ejemplo:
Creamos un desencadenador que se dispara cada vez que se ejecuta un "insert" sobre la tabla
"libros":
Sintaxis básica:
Analizamos la sintaxis:
• "create trigger" junto al nombre del disparador; "on" seguido del nombre de la tabla para la cual se
establece el trigger.
• Luego de "for" se coloca el evento (en este caso "delete"), lo que indica que las eliminaciones sobre la
tabla activarán el trigger.
• Luego de "as" se especifican las condiciones que determinan cuando un intento de eliminación causa las
acciones que el trigger realizará.
El disparador del siguiente ejemplo se crea para la tabla "ventas", para que cada vez que se elimine un
registro de "ventas", se actualice el campo "stock" de la tabla "libros" (por ejemplo, si el comprador
devuelve los libros comprados):
Cuando se activa un disparador "delete", los registros eliminados en la tabla del disparador se agregan
a una tabla llamada "deleted". La tabla "deleted" es una tabla virtual que conserva una copia de los
registros eliminados; tiene una estructura similar a la tabla en que se define el disparador, es decir, la
tabla en que se intenta la acción.
Si se ejecuta un "delete" sobre "libros" que afecte a varios registros, se activa el disparador y evita la
transacción.
Si se ejecuta el siguiente "delete", que afecta a un solo registro, se activa el disparador y permite la
transacción:
delete from libros where codigo=5;
Para utilizar un Trigger de tipo instead of crearemos una vista llamada SociosEstrategicos con los Clientes
(Customers) y los Proveedores (Suppliers)
Creamos la vista
Create view VistaSociosEstrategicos
As
select C.CustomerID ‘CodigoSocio’, C.CompanyName As ‘Socio’,
C.Country As ‘País’, ‘Cliente’ As Tipo
from Customers As C
union all
select S.SupplierID , S.CompanyName ,
S.Country , ‘Proveedor’ As Tipo
from Suppliers As S
go
El Trigger se creará para la vista, será de tipo Instead Of
Insertar un Proveedor
insert into VistaSociosEstrategicos
values (‘BT599′,’Limbo Almacenes’,’Spain’,’Proveedor’)
go
Más ejemplos de desencadenadores
Use Ejemplo
GO
CREATE TRIGGER NuevoPedido
ON Pedidos
FOR INSERT
AS
UPDATE RepVentas
SET VENTAS =VENTAS + INSERTED.IMPORTE
FROM REPVENTAS INNER JOIN INSERTED
ON REPVENTAS.NUM_EMPL = INSERTED.REP
UPDATE PRODUCTOS
SET EXISTENCIAS = EXISTENCIAS - INSERTED.CANT
FROM PRODUCTOS INNER JOIN INSERTED
ON PRODUCTOS.ID_FAB = INSERTED.FAB
AND PRODUCTOS.ID_PRODUCTO = INSERTED.PRODUCTO
GO
Ejemplo: Desencadenadores DDL
Todos los mensajes que se originan dentro del desencadenador que alcanzaría
normalmente el usuario, como los mensajes de error y los mensajes de la instrucción
PRINT, se desvían al registro de errores de SQL Server.
USE master;
GO CREATE LOGIN login_test
WITH PASSWORD = '3KHJ6dhx(0xVYsdf' MUST_CHANGE, CHECK_EXPIRATION = ON;
GO GRANT VIEW SERVER STATE TO login_test;
GO CREATE TRIGGER connection_limit_trigger ON ALL SERVER WITH EXECUTE AS
'login_test' FOR LOGON AS
BEGIN
IF ORIGINAL_LOGIN()= 'login_test' AND (SELECT COUNT(*) FROM
sys.dm_exec_sessions WHERE is_user_process = 1 AND original_login_name = 'login_test') > 3
ROLLBACK;
END;
Diferencias entre desencadenadores DML y
DDL
Los desencadenadores DDL y DML se utilizan con finalidades distintas.
Se aplican a todos los comandos de un solo tipo en toda una base de datos o todo un
servidor.
Los desencadenadores DDL y DML se crean, modifican y quitan con una sintaxis
Transact-SQL similar y tienen un comportamiento parecido.
Ejemplo 2
Utilizar un trigger DML con un mensaje de aviso. El siguiente trigger DML imprime
un mensaje en el cliente cuando alguien intenta agregar o cambiar datos en la tabla
Customer.