TRIGGERS (GATILHOS)
Uma TRIGGER um tipo especial de sp que executado automaticamente em conseqncia de uma modificao (INSERT, UPDATE, DELETE) na tabela na qual a TRIGGER foi configurada. Chama-se disparar a trigger a execuo automtica da mesma No podem ser executadas usando EXEC.
Uma TRIGGER sempre associada a uma tabela, porm os comandos que formam a TRIGGER podem acessar dados de outras tabelas. Ex: dadas as tabelas
Nota_Fiscal(Num_nota, valor_total) Produto(Cod_Prod, nome, preo, estoque) Nota_Prod(Num_nota, Cod_Prod, quantidade)
Pode-se criar uma Trigger para a operao de INSERT na tabela Nota_Prod. Sempre que for inserido um novo item de pedido na tabela Nota_Prod ser disparada um Trigger que atualiza o nvel de estoque do produto que est sendo vendido
3
Pode-se usar TRIGGERS para excluso e atualizao em cascata Se o comando que est sendo executado violar a definio de uma CONSTRAINT definida, a TRIGGER no ir disparar
4
AFTER
AFTER: disparada APS todos os comandos de uma TRIGGER associada com um DELETE, UPDATE e INSERT terem sidos executados
INSTEAD OF disparada ANTES dos comandos serem executados. Processa as constraints antes da execuo da trigger.
O SQLServer 2000/2005 permite especificar TRIGGERs em Views (INSTEAD OF) Nos comandos que definem a TRIGGER podese usar a maioria dos comandos SQL, inclusive estruturas IF..ELSE e WHILE.
No so permitidos os seguintes comandos: ALTER DATABASE, CREATE DATABASE, DROP DATABASE, LOAD DATABASE, LOAD LOG, RESTORE DATABASE, RESTORE LOG, RECONFIGURE
6
Essas tabelas existem apenas na memria do servidor, no sendo gravadas em disco Os registros dessas tabelas so acessveis somente durante a execuo da TRIGGER Para referenciar essas tabelas temporrias dentro da TRIGGER usa-se os nomes
DELETED INSERTED
7
A tabela DELETED armazena cpias de registros afetados por um comando DELETE ou UPDATE
Armazena os registros antes da alterao
A tabela INSERTED armazena cpias dos registros afetados por um comando INSERT ou UPDATE.
Os registros na tabela INSERTED so cpias dos novos registros da tabela da tabela que disparou a TRIGGER
8
Sintaxe:
CREATE TRIGGER nome_da_trigger ON nome_da_tabela ou nome_da_view [WITH ENCRYPTION] {FOR | AFTER| INSTEAD OF} {[DELETE] [,] [INSERT] [,] [UPDATE]} AS comando 1 comando 2 ..... comando n
9
Exemplo: Criar uma TRIGGER que evite que sejam inseridos novos clientes na tabela CLIENTE (banco de dados LOCADORA) em que o compo UF seja igual a AC ou PA. Essa TRIGGER ser criada para a ao INSERT.
CREATE TRIGGER TG_Permite_UF ON Cliente FOR INSERT AS IF EXISTS (SELECT * FROM INSERTED WHERE UF_CLI IN ('PA', 'AC')) BEGIN PRINT 'INSERO DE REGISTRO CANCELADA.' PRINT 'ESTADO (UF) PROIBIDO!!' ROLLBACK END ELSE PRINT 'PAS PERMITIDO!'
10
Crie uma TRIGGER calcule e insera a data de devoluo prevista na tabela EMP_DEV sempre que uma fita for emprestada
CREATE TRIGGER tg_CALCULA_DATA_DEV_PREV ON EMP_DEV FOR INSERT AS IF EXISTS (SELECT * FROM INSERTED) BEGIN UPDATE EMP_DEV SET DATA_DEV_PREV = DATEADD(DD,1,DATA_EMP) END
11
Crie uma TRIGGER que calcule e insira a data de devoluo prevista na tabela EMP_DEV sempre que uma fita for emprestada. Se a fita for de catlogo ela tem dois dias para ser entregue. Lanamentos podem ficar locadas apenas 1 dia. alter table Fita add Tipo_fita varchar (10) Constraint CKTipo_fita check (Tipo_fita in ('catlogo','Lanamento'))
CREATE TRIGGER tg_CALCULA_DATA_DEV_PREV ON EMP_DEV FOR INSERT AS IF EXISTS (SELECT * FROM INSERTED INNER JOIN FITA ON FITA.COD_FITA = INSERTED.COD_FITA WHERE Tipo_fita = 'catlogo') BEGIN UPDATE EMP_DEV SET DATA_DEV_PREV = DATEADD(DD,2,DATA_EMP) WHERE emp_dev.cod_fita = (select inserted.cod_fita from inserted) END ELSE IF EXISTS (SELECT * FROM INSERTED INNER JOIN FITA ON FITA.COD_FITA = INSERTED.COD_FITA WHERE Tipo_fita = 'Lanamento') BEGIN UPDATE EMP_DEV SET DATA_DEV_PREV = DATEADD(DD,1,DATA_EMP) WHERE emp_dev.cod_fita = (select inserted.cod_fita from inserted) END 13
Crie uma TRIGGER que calcule o valor da multa de um cliente sempre que o mesmo devolver a fita locadora. Isso significa que toda a vez que o campo dev_efet for preenchido (UPDATE) a multa ser calculada.
CREATE TRIGGER tg_CALCULA_MULTA ON EMP_DEV FOR UPDATE AS IF UPDATE (DATA_DEV_EFET) BEGIN UPDATE EMP_DEV
SET multa = 1.5 * DATEDIFF(DD,DATA_DEV_PREV,DATA_DEV_EFET)
WHERE DATEDIFF(DD,DATA_DEV_PREV,DATA_DEV_EFET) > 0 END IF UPDATE (DATA_DEV_EFET) BEGIN UPDATE EMP_DEV SET multa = 0 WHERE DATEDIFF(DD,DATA_DEV_PREV,DATA_DEV_EFET) <= 0 14 END
Vamos supor que, por ordem da admistraao no seja permitido fazer alteraes e inseres na tabela Fornecedor. Para garantir esta norma implemente um trigger que dispare em resposta a comandos UPDATE e INSERT na tabela Fornecedor. Esta trigger deve emitir um aviso de que as alteraes e inseres foram suspensas e registrar em uma tabela o nome do usurio que tentou fazer a alterao e o nome do fornecedor que tentou-se alterar ou inserir. CREATE TABLE TENTOU_ALTERAR ( FORNECEDOR VARCHAR (50) NOT NULL, USURIO CHAR (30) NOT NULL )
15
CREATE TRIGGER Tg_NO_ALTERAINSERE_FORNECEDOR ON FORNECEDOR FOR INSERT, UPDATE AS -- VARIAVEL QUE SER UTILIZADA NA TRIGGER DECLARE @NOME_FORNECEDOR VARCHAR(50) -- VERIFICA SE FOI FEITA ALGUMA ALTERAO (INSERT OU UPDATE) IF EXISTS (SELECT * FROM DELETED) BEGIN SET @NOME_FORNECEDOR = (SELECT NOME_FORN FROM DELETED) PRINT 'VC NO PODE ALTERAR O REGISTRO DE UM FORNECEDOR' ROLLBACK INSERT INTO TENTOU_ALTERAR VALUES (@NOME_FORNECEDOR, CURRENT_USER) END IF EXISTS (SELECT * FROM INSERTED) BEGIN SET @NOME_FORNECEDOR = (SELECT NOME_FORN FROM INSERTED) PRINT 'VC NO PODE INSERIR NOVOS FORNECEDORES' ROLLBACK INSERT INTO TENTOU_ALTERAR VALUES (@NOME_FORNECEDOR, CURRENT_USER) END
16
17