Ich habe einen Tabellenauslöser für UPDATE und INSERT , der einer anderen Tabelle eine Zeile hinzufügt. Es muss nur eine Zeile hinzugefügt werden, wenn eine von vier Spalten geändert wird. Ich habe versucht, IF UPDATE (col) zu verwenden, um auf Änderungen zu testen, aber es hat einen blinden Fleck. Es wird nur getestet, ob ein Wert eingegangen ist. Ich muss tiefer gehen, ich muss die alten und neuen Werte vergleichen, um festzustellen, ob eine echte Änderung eingetreten ist. Es muss sowohl mit INSERT als auch mit UPDATE funktionieren.
Bei einem UPDATE ist das einfach, da sowohl die eingefügten als auch die gelöschten Tabellen Werte haben, die ich innerhalb des Triggers vergleichen kann. Für das INSERT hat jedoch nur die Insert-Tabelle Werte. Wie gehe ich mit diesem INSERT-Fall um, da ich dies alles im selben Trigger benötige?
Hier ist das Skript des Triggers, den ich ändern möchte:
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
Antworten:
Sie können sowohl INSERT als auch UPDATE mit einem EXCEPT-Set-Operator verarbeiten. Die EXISTS werden nur dann als TRUE ausgewertet, wenn es sich nur um ein INSERT handelt oder wenn es sich um ein UPDATE mit unterschiedlichen Werten für eine dieser Spalten handelt.
quelle
EXISTS
überprüft, ob sich eine Zeile geändert hat. Wenn Sie die Einfügung von der Frage fernhalten, protokollieren Sie alle aktualisierten Zeilen, wenn sich nur eine auf sinnvolle Weise ändert.Wenn ein Update mehrere Zeilen betreffen kann, müssen Sie sich vor zwei Dingen schützen:
AT_Person_To_Push
. Wenn 5 Zeilen aktualisiert werden, aber nur 2 auf eine Weise aktualisiert werden, die uns wichtig ist, müssen wir nur die 2 relevanten Zeilen verarbeiten.So würde ich damit umgehen:
inserted
mitdeleted
, dainserted
Zeilen für Einfügungen und Aktualisierungen vorhanden sind, währenddeleted
nur Zeilen für Aktualisierungen vorhanden sind.EXISTS
mitEXCEPT
Zeilen zu finden , wo dieinserted
Werte aus den verschiedendeleted
Werten. Sie können nicht verwenden,i.First_Name != d.First_Name OR i.Last_Name != d.Last_Name...
da die gelöschte Tabelle leer ist (und LEFT JOIN Nullen zurückgibt), wenn der Trigger ein INSERT verarbeitet.AT_Person_To_Push
.quelle
Versuche dies,
quelle