Eu tenho um gatilho de tabela em UPDATE e INSERT que adiciona uma linha a outra tabela. Ele só precisa adicionar uma linha se uma das quatro colunas for alterada. Tentei usar o IF UPDATE (col) para testar alterações, mas ele tem um ponto cego. Ele apenas testa a entrada de algum valor. Preciso ir mais fundo, preciso comparar os valores antigos e os novos para ver se uma mudança verdadeira ocorreu. Ele tem que trabalhar com INSERT e UPDATE.
No caso de um UPDATE, isso é fácil, porque as tabelas inseridas e excluídas têm valores que posso comparar dentro do gatilho. No entanto, para o INSERT, apenas a tabela de inserção possui valores. Como eu preciso disso tudo no mesmo gatilho, como lidar com esse caso INSERT?
Aqui está o script do gatilho que eu quero modificar:
ALTER TRIGGER [dbo].[trATPerson_alter]
ON [mydb].[dbo].[AT_Person]
AFTER INSERT,UPDATE
AS
BEGIN
SET NOCOUNT ON;
-- Not all updates require a push
IF (UPDATE([First_Name]) OR UPDATE([Last_Name]) OR UPDATE([JobCode]) OR UPDATE([Inactive]))
BEGIN
INSERT INTO [mydb].[dbo].[AT_Person_To_Push] (
[Facility],
[VendorID],
[Person_code],
[First_Name],
[Last_Name],
[JobCode],
[Alink],
[Inactive]
)
SELECT [Facility],
[VendorID],
[Person_code],
[First_Name],
[Last_Name],
[JobCode],
[Alink],
[Inactive]
FROM inserted
END
END
Respostas:
Você pode manipular INSERT e UPDATE com um operador EXCEPT set. O EXISTS avaliará TRUE apenas se for apenas um INSERT ou se for um UPDATE com valores diferentes para qualquer uma dessas colunas.
fonte
EXISTS
verifica se qualquer linha foi alterada. Se você mantiver a inserção da pergunta, registrará todas as linhas atualizadas quando apenas uma for alterada de maneira significativa.Caso uma atualização possa afetar várias linhas, você deve se proteger de duas coisas:
AT_Person_To_Push
. Se 5 linhas são atualizadas, mas apenas 2 são atualizadas da maneira que mais nos interessa, precisamos processar apenas as 2 linhas relevantes.Aqui está como eu lidaria com isso:
inserted
emdeleted
, porqueinserted
terá linhas para inserções e atualizações, enquantodeleted
só terá linhas para atualizações.EXISTS
comEXCEPT
para encontrar linhas em que osinserted
valores diferem dosdeleted
valores. Você não pode usari.First_Name != d.First_Name OR i.Last_Name != d.Last_Name...
porque a tabela excluída estará vazia (e o LEFT JOIN retornará nulos) quando o gatilho estiver manipulando um INSERT.AT_Person_To_Push
.fonte
Tente isso,
fonte