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.
Antworten
Zu viele Anzeigen?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
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
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.
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;
- See previous answers
- Weitere Antworten anzeigen