Mam wyzwalacz tabeli na UPDATE i INSERT, który dodaje wiersz do innej tabeli. Wystarczy dodać wiersz, jeśli jedna z czterech kolumn zostanie zmieniona. Próbowałem użyć JEŻELI AKTUALIZACJI (kol.) Do testowania zmian, ale ma martwy punkt. Testuje tylko, że pojawiła się pewna wartość. Muszę wejść głębiej, muszę porównać stare i nowe wartości, aby zobaczyć prawdziwą zmianę. Musi współpracować zarówno z INSERT, jak i UPDATE.
W przypadku UPDATE jest to łatwe, ponieważ zarówno wstawione, jak i usunięte tabele mają wartości, które mogę porównać w ramach wyzwalacza. Jednak dla INSERT tylko tabela wstawiania ma wartości. Ponieważ potrzebuję tego wszystkiego w tym samym wyzwalaczu, jak poradzić sobie z tą sprawą INSERT?
Oto skrypt wyzwalacza, który chcę zmodyfikować:
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
Odpowiedzi:
Możesz obsługiwać zarówno WSTAW, jak i AKTUALIZACJĘ za pomocą operatora zestawu EXCEPT. EXISTS oceni PRAWDA tylko wtedy, gdy jest to WSTAWKA lub AKTUALIZACJA z różnymi wartościami dla dowolnej z tych kolumn.
źródło
EXISTS
sprawdza, czy dowolny wiersz się zmienił. Jeśli ukryjesz wstawkę przed pytaniem, będziesz zapisywać wszystkie zaktualizowane wiersze, gdy tylko jedna zmieni się w znaczący sposób.Jeśli aktualizacja może wpływać na wiele wierszy, musisz zabezpieczyć się przed dwiema rzeczami:
AT_Person_To_Push
. Jeśli 5 wierszy zostanie zaktualizowanych, ale tylko 2 zostaną zaktualizowane w sposób, na którym nam zależy, musimy przetworzyć tylko 2 odpowiednie wiersze.Oto jak bym sobie z tym poradził:
inserted
zdeleted
, ponieważinserted
będą miały wiersze dla wstawek i aktualizacji, adeleted
będą miały tylko wiersze dla aktualizacji.EXISTS
pomocą,EXCEPT
aby znaleźć wiersze, w którychinserted
wartości różnią się oddeleted
wartości. Nie możesz użyć,i.First_Name != d.First_Name OR i.Last_Name != d.Last_Name...
ponieważ usunięta tabela będzie pusta (a LEFT JOIN zwróci null), gdy wyzwalacz obsługuje INSERT.AT_Person_To_Push
.źródło
Spróbuj tego,
źródło