2012-03-24 10 views
7

Ich mache ein paar Änderungen an einer Legacy-Anwendung, die auf SQL Server 2000 gebaut wurde, unnötig zu sagen, dass ich nur das absolute Minimum in der Angst machen will, dass es einfach alles auseinander fallen kann.INSTEAD OF UPDATE Trigger - ist das möglich?

Ich habe eine große Tabelle von Benutzern, TbUsers, mit einem BIT-Flag für IsDeleted. Ich möchte alle aktuellen und zukünftigen IsDeleted = 1 Benutzerdatensätze in meine Archivtabelle tbDeletedUsers archivieren.

Verschieben der derzeit gelöschten Benutzer ist einfach, aber ich möchte eine Möglichkeit, alle zukünftigen Benutzer verschieben, wo das IsDeleted Flag gesetzt ist. Ich könnte einen Standard-AFTER-Trigger für die Spalte verwenden, jedoch beabsichtige ich, der tbUser-Tabelle einige Einschränkungen hinzuzufügen, die dies verletzen würden, was ich für meinen INSTEAD OF UPDATE-Trigger möchte und stattdessen den Record in die Archiv-Tabelle verschiebe?

Ich denke, meine Frage ist ... ist es möglich, einen INSTEAD OF UPDATE-Trigger auf das Update einer einzelnen Spalte auszulösen? Dies ist, was ich bisher habe:

CREATE TRIGGER trg_ArchiveUsers 
INSTEAD OF UPDATE ON tbUsers 
AS 
    BEGIN 
     ... 
    END 
GO 

Wenn so ein Beispiel (SQL 2000 kompatibel) würde sehr geschätzt werden!

Antwort

12

Mit dem UPDATE(columnname) Test können Sie in einen Trigger überprüfen, ob eine bestimmte Spalte aktualisiert wurde (und dann bestimmte Aktionen ausführen), aber Sie können keinen Trigger Feuer nur auf die Aktualisierung einer bestimmten Spalte haben . Es wird ausgelöst, sobald das Update durchgeführt wird, unabhängig davon, welche Spalte das Ziel des Updates war.

Also, wenn Sie denken, Sie haben einen INSTEAD OF UPDATE Trigger zu verwenden, müssen Sie zwei Arten von Aktionen in sie umzusetzen:

1) einfügen in tbDeletedUsers + aus tbUsers löschen - wenn IsDeleted aktualisiert (oder , genauer, aktualisiert und eingestellt auf 1);

2) update tbUsers normal - wenn IsDeleted nicht aktualisiert (oder aktualisiert, aber nicht auf 1 eingestellt).

Da mehr als eine Zeile mit einer einzigen UPDATE-Anweisung aktualisiert werden kann, müssen Sie möglicherweise auch berücksichtigen, dass in einigen Zeilen IsDeleted auf 1 gesetzt ist und andere nicht.

Ich bin kein großer Fan von INSTEAD OF Trigger, aber wenn ich wirklich ein wie das Ihre für eine Aufgabe habe zu verwenden, könnte ich den UPDATE() Test und implementieren die Auslöser wie dies auslassen:

CREATE TRIGGER trg_ArchiveUsers 
ON tbUsers 
INSTEAD OF UPDATE 
AS 
BEGIN 
    UPDATE tbUsers 
    SET 
    column = INSERTED.column, 
    … 
    FROM INSERTED 
    WHERE INSERTED.key = tbUsers.key 
    AND INSERTED.IsDeleted = 0 
    ; 
    DELETE FROM tbUsers 
    FROM INSERTED 
    WHERE INSERTED.key = tbUsers.key 
    AND INSERTED.IsDeleted = 1 
    ; 
    INSERT INTO tbDeletedUsers (columns) 
    SELECT columns 
    FROM INSERTED 
    WHERE IsDeleted = 1 
    ; 
END 
+1

UPDATES (columnName) ist in SQL Server nicht vorhanden. Verwenden Sie stattdessen COLUMNS_UPDATED (columnName). http://msdn.microsoft.com/en-us/library/ms186329.aspx –

+1

Vielen Dank für den Kommentar. Sie haben recht, es gibt keine UPDATES() -Funktion in SQL Server, noch UPDATED(), wie ich anfangs geschrieben habe. Es heißt eigentlich [UPDATE()] (http://msdn.microsoft.com/en-us/library/ms187326.aspx). Bearbeiten meiner Antwort und nochmals Danke, dass ich meinen Fehler bemerkt habe. –

+0

Und Sie scheinen auch falsch zu sein, denn COLUMNS_UPDATED() akzeptiert keinen Parameter. Es gibt eine Bitmaske zurück, die alle Spalten widerspiegelt, die von der Anweisung betroffen sind, die den Trigger aufgerufen hat. Ich habe diese Funktion nie benutzt, obwohl ich aus dem Handbuch eine ungefähre Vorstellung davon habe, wie man sie benutzt. –