No SQL Server, você pode criar gatilhos DML que executam código somente quando uma coluna específica é atualizada.
O gatilho ainda é acionado, mas você pode testar se uma coluna específica foi atualizada ou não e, em seguida, executar o código somente se essa coluna tiver sido atualizada.
Você pode fazer isso usando o
UPDATE()
função dentro do seu gatilho. Esta função aceita o nome da coluna como seu argumento. Ele retorna um booleano. Exemplo
Aqui está a tabela:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
E aqui está o gatilho:
CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE (c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
Neste exemplo, crio uma tabela chamada
t1
e um gatilho chamado trg_t1
. Eu uso um
IF
instrução junto com o UPDATE()
função para testar se o c1
coluna foi atualizada. Quando o gatilho é executado, ele só executará o código subsequente se essa condição for verdadeira.
Acione o gatilho
Vamos inserir uma linha, mas inseriremos apenas um valor no
c1
coluna. INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 0 | 1 | +------+------+------+------+
Como esperado, o gatilho foi acionado e a coluna
c3
também foi atualizado. Isso aconteceu porque incluí o
INSERT
argumento na definição do meu gatilho (ou seja, eu especifiquei AFTER INSERT, UPDATE
o que significa que o gatilho é acionado sempre que os dados são inseridos ou atualizados). Se eu tivesse especificado apenas AFTER UPDATE
, ele não teria disparado quando eu inseri dados – ele só dispararia sempre que eu atualizasse os dados existentes. Lembre-se que a tabela foi definida com
DEFAULT 0
, então a coluna c2 assumiu o padrão zero. Agora vamos atualizar o
c1
coluna. UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 0 | 2 | +------+------+------+------+
Novamente, o
c3
coluna foi atualizada junto com c1
. Agora vamos fazer uma atualização para o
c2
coluna (esta coluna não está incluída no gatilho). UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 2 | +------+------+------+------+
Desta vez,
c2
foi atualizado, mas c3
não era. Isso porque o c1
a coluna não foi atualizada e nosso gatilho apenas atualiza c3
quando c1
é atualizada. A mesma coisa aconteceria se tivéssemos inserido uma linha sem especificar c1 no
INSERT
demonstração. E se eu atualizar a coluna com o mesmo valor?
Se você atualizar uma coluna com o mesmo valor, o
UPDATE()
função retornará verdadeiro. Aqui está um exemplo.
Sabemos de nossos exemplos anteriores que a coluna c1 contém um valor de
2
. Vamos atualizar explicitamente essa coluna com o mesmo valor:
1
UPDATE t1
SET c1 = 2
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 3 | +------+------+------+------+
Então agora
c3
foi incrementado, mesmo que o valor para c1
ainda é o mesmo. Vamos fazê-lo novamente, mas desta vez defina-o para si mesmo (ou seja, altere
c1 = 1
para c1 = c1
). UPDATE t1
SET c1 = c1
WHERE id = 1;
SELECT * FROM t1;
Resultado:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 4 | +------+------+------+------+
Novamente,
c3
tem incrementado. Tentativas de atualização malsucedidas
É importante observar que o
UPDATE()
função meramente indica se um INSERT
ou UPDATE
tentativa foi feito em uma coluna especificada de uma tabela ou exibição. Ele ainda retornará true se a tentativa não for bem-sucedida.