Ao criar um gatilho no SQL Server, você tem a opção de dispará-lo em conjunto com a instrução de gatilho (ou seja, a instrução SQL que disparou o gatilho) ou dispará-lo em vez disso dessa afirmação.
Para disparar o gatilho em vez da instrução de acionamento, use
INSTEAD OF
argumento. Isso contrasta com o uso do
FOR
ou AFTER
argumentos. Quando você usa esses argumentos, o acionador é acionado somente quando todas as operações especificadas na instrução SQL de acionamento são iniciadas com êxito. Exemplo
Crie uma tabela de exemplo:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
Crie o acionador:
CREATE TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);
Insira uma linha de amostra:
INSERT INTO t1 (c1, c2, c3)
VALUES (1, 1, 1);
SELECT * FROM t1;
Aqui está o que temos até agora:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 1 | +------+------+------+------+
Agora vamos executar um
UPDATE
declaração contra a tabela (isso irá disparar o gatilho). UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 2 | +------+------+------+------+
Como esperado, o
UPDATE
A instrução na instrução de acionamento foi substituída pela do acionador. Meu gatilho especificou que sempre que houver uma tentativa de atualização da tabela, atualize o
c3
coluna em vez disso. Executar somente quando uma coluna específica é atualizada
Você também pode usar o
UPDATE()
função para especificar o código a ser executado somente quando uma coluna especificada for atualizada. Por exemplo, poderíamos alterar nosso gatilho da seguinte forma:
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
IF ( UPDATE(c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
Agora execute o
UPDATE
anterior declaração novamente:UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Novamente, o
c3
coluna é incrementada. Mas, agora vamos tentar atualizar o
c2
coluna:UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Nada muda. O
c3
coluna permanece a mesma. Nem mesmo o
c2
coluna é atualizada. Isso ocorre porque o gatilho ainda é executado em vez da instrução de gatilho. Executar Trigger em vez de DELETE
Podemos modificar o gatilho para executar em vez de qualquer
DELETE
declarações. ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);
Agora vamos tentar excluir todas as linhas e, em seguida, selecionar todas as linhas da tabela.
DELETE FROM t1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 4 | +------+------+------+------+
Observe que para esse gatilho funcionar corretamente, tive que consultar o
deleted
tabela no meu gatilho (em oposição ao inserted
tabela nos exemplos anteriores). Essas duas tabelas são criadas e gerenciadas pelo SQL Server.
O
deleted
tabela armazena cópias das linhas afetadas durante DELETE
e UPDATE
declarações. Durante a execução de um DELETE
ou UPDATE
instrução, as linhas são excluídas da tabela de gatilhos e transferidas para a tabela excluída. O
inserted
tabela armazena cópias das linhas afetadas durante INSERT
e UPDATE
declarações. Durante uma transação de inserção ou atualização, novas linhas são adicionadas à tabela inserida e à tabela acionadora. As linhas na tabela inserida são cópias das novas linhas na tabela de gatilhos. Algumas restrições a serem lembradas
Você pode definir no máximo um
INSTEAD OF
acionado por INSERT
, UPDATE
, ou DELETE
declaração em uma tabela ou exibição. Você não pode definir
INSTEAD OF
acionados em visualizações atualizáveis que usam WITH CHECK OPTION
.