it-swarm.com.de

Wie wird ein T-SQL-Trigger, der nur bei echten Änderungen ausgelöst wird, vorgenommen?

Ich habe eine Tabelle Auslöser für UPDATE und INSERT, die 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
9
WillG

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.

IF EXISTS (
           SELECT First_Name, Last_Name, JobCoe, Inactive FROM inserted
           EXCEPT
           SELECT First_Name, Last_Name, JobCoe, Inactive FROM deleted
          )
BEGIN...
18
SQLRaptor

Wenn ein Update mehrere Zeilen betreffen kann, müssen Sie sich vor zwei Dingen schützen:

  1. Wir möchten Aktualisierungen in Betracht ziehen, bei denen Werte zwischen ähnlichen Zeilen ausgetauscht werden. Wenn es zwei John Smiths gibt, deren JobCodes aktualisiert werden müssen (erster John von 1 bis 2; zweiter John von 2 bis 1), müssen wir vorsichtig sein, um zu sagen, dass beide aktualisiert wurden.
  2. Wir wollen nur die geänderten Zeilen in AT_Person_To_Push Protokollieren. 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:

  1. Verbinden Sie inserted mit deleted, da inserted Zeilen für Einfügungen und Aktualisierungen enthält, während deleted nur Zeilen für Aktualisierungen enthält.
  2. Verwenden Sie EXISTS mit EXCEPT, um Zeilen zu finden, in denen sich die inserted -Werte von den deleted -Werten unterscheiden. Sie können i.First_Name != d.First_Name OR i.Last_Name != d.Last_Name... Nicht verwenden, da die gelöschte Tabelle leer ist (und LEFT JOIN Nullen zurückgibt), wenn der Trigger ein INSERT verarbeitet.
  3. Fügen Sie nur die betroffenen Zeilen in AT_Person_To_Push Ein.
ALTER TRIGGER [dbo].[trATPerson_alter] 
   ON  [mydb].[dbo].[AT_Person]
   AFTER INSERT,UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    INSERT INTO [mydb].[dbo].[AT_Person_To_Push] (
            [Facility],
            [VendorID],
            [Person_code],
            [First_Name],
            [Last_Name],
            [JobCode],
            [Alink],
            [Inactive]
        )
    SELECT  i.[Facility],
            i.[VendorID],
            i.[Person_code],
            i.[First_Name],
            i.[Last_Name],
            i.[JobCode],
            i.[Alink],
            i.[Inactive]
    FROM inserted i
         LEFT JOIN deleted d
           ON i.Person_code = d.Person_code
    -- Check for changes that require a Push
    WHERE EXISTS (SELECT i.[First_Name], i.[Last_Name], i.[JobCode], i.[Inactive]
                  EXCEPT
                  SELECT d.[First_Name], d.[Last_Name], d.[JobCode], d.[Inactive]);
END
2
Steven Hibble

Versuche dies,

Declare @Acton int=0

If exists (Select 1 from inserted)
set @Acton=1

If exists (Select 1 from deleted)
set @[email protected]+2

if(@Action=1) -- Only insert

if(@Action=3) -- Only Update
begin
IF (UPDATE([First_Name]) OR UPDATE([Last_Name]) OR UPDATE([JobCode]) OR UPDATE([Inactive]))
Begin

End
end

if(@Action=2) -- Only Delete
1
KumarHarsh