204 Stimmen

Insert-Update-Trigger, wie man feststellt, ob Insert oder Update

Ich muss einen Einfüge- und Aktualisierungs-Trigger für Tabelle A schreiben, der alle Zeilen aus Tabelle B löscht, deren eine Spalte (z. B. Desc) Werte enthält, die dem Wert entsprechen, der in die Spalte der Tabelle A (z. B. Col1) eingefügt/aktualisiert wurde. Wie würde ich vorgehen, um es so zu schreiben, dass ich sowohl Aktualisierungs- als auch Einfügefälle behandeln kann. Wie würde ich feststellen, ob der Trigger für eine Aktualisierung oder eine Einfügung ausgeführt wird.

199voto

gbn Punkte 407102

Auslöser haben besondere INSERTED y DELETED Tabellen, um "Vorher"- und "Nachher"-Daten zu erfassen. Sie können also etwas verwenden wie IF EXISTS (SELECT * FROM DELETED) um eine Aktualisierung zu erkennen. Sie haben nur Zeilen in DELETED bei der Aktualisierung, aber es gibt immer Zeilen in INSERTED .

Suchen Sie nach "eingefügt" in TRIGGER ERZEUGEN .

Bearbeiten, 23. November 2011

Nach Kommentar, diese Antwort ist nur für INSERTED y UPDATED Auslöser.
Offensichtlich können DELETE-Trigger nicht "always rows in" haben INSERTED "wie ich oben sagte

143voto

net_prog Punkte 9382
CREATE TRIGGER dbo.TableName_IUD
ON dbo.TableName
AFTER INSERT, UPDATE, DELETE
AS 
BEGIN
    SET NOCOUNT ON;

    --
    -- Check if this is an INSERT, UPDATE or DELETE Action.
    -- 
    DECLARE @action as char(1);

    SET @action = 'I'; -- Set Action to Insert by default.
    IF EXISTS(SELECT * FROM DELETED)
    BEGIN
        SET @action = 
            CASE
                WHEN EXISTS(SELECT * FROM INSERTED) THEN 'U' -- Set Action to Updated.
                ELSE 'D' -- Set Action to Deleted.       
            END
    END
    ELSE 
        IF NOT EXISTS(SELECT * FROM INSERTED) RETURN; -- Nothing updated or inserted.

    ...

    END

117voto

MikeTeeVee Punkte 17130

Viele dieser Vorschläge berücksichtigen nicht, wenn Sie eine Löschanweisung ausführen, die nichts löscht.
Angenommen, Sie versuchen zu löschen, wobei eine ID einem Wert entspricht, der in der Tabelle nicht vorhanden ist.
Ihr Trigger wird immer noch aufgerufen, aber in den Tabellen Gelöscht oder Eingefügt ist nichts zu finden.

Verwenden Sie dies, um sicher zu sein:

--Determine if this is an INSERT,UPDATE, or DELETE Action or a "failed delete".
DECLARE @Action as char(1);
    SET @Action = (CASE WHEN EXISTS(SELECT * FROM INSERTED)
                         AND EXISTS(SELECT * FROM DELETED)
                        THEN 'U'  -- Set Action to Updated.
                        WHEN EXISTS(SELECT * FROM INSERTED)
                        THEN 'I'  -- Set Action to Insert.
                        WHEN EXISTS(SELECT * FROM DELETED)
                        THEN 'D'  -- Set Action to Deleted.
                        ELSE NULL -- Skip. It may have been a "failed delete".   
                    END)

Besonderen Dank an @KenDog und @Net_Prog für ihre Antworten.
Ich habe dies aus ihren Skripten erstellt.

20voto

Sat Punkte 1111

Ich verwende die folgende, es auch korrekt erkennen löschen Anweisungen, die nichts löschen:

CREATE TRIGGER dbo.TR_TableName_TriggerName
    ON dbo.TableName
    AFTER INSERT, UPDATE, DELETE
AS
BEGIN
    SET NOCOUNT ON;

    IF NOT EXISTS(SELECT * FROM INSERTED)
        -- DELETE
        PRINT 'DELETE';
    ELSE
    BEGIN
        IF NOT EXISTS(SELECT * FROM DELETED)
            -- INSERT
            PRINT 'INSERT';
        ELSE
            -- UPDATE
            PRINT 'UPDATE';
    END
END;

17voto

Declare @Type varchar(50)='';
IF EXISTS (SELECT * FROM inserted) and  EXISTS (SELECT * FROM deleted)
BEGIN
    SELECT @Type = 'UPDATE'
END
ELSE IF EXISTS(SELECT * FROM inserted)
BEGIN
    SELECT @Type = 'INSERT'
END
ElSE IF EXISTS(SELECT * FROM deleted)
BEGIN
    SELECT @Type = 'DELETE'
END

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X