Wenn man in T-SQL einen Trigger auf eine Tabelle legt und diese soll nach einem Löschvorgang ebenfalls etwas anderes machen, dann stoßt man auf das folgende Problem. Solange man nur eine Zeile löscht, ist alles in Ordnung, sobald man aber mehrere Datensätze löscht, kann es passieren, dass nur der erste Trigger greift. Der Grund ist, wie man auf die deleted Tabelle zugreift.
Nutzt man SELECT TOP 1 FROM deleted, so bekommt man auch nur die erste ID. Löscht man mehrere Datensätze, befinden sich aber mehrere IDs in der deleted Tabelle.
Die Lösung ist, dass man Cursor an dieser Stelle verwendet, die Zeile für Zeile, alle IDs bearbeiten.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/****** Object: Trigger [Core].[trDeleteTrigger] SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER TRIGGER [Core].[trDeleteTrigger] ON [Core].[ExampleTable] FOR DELETE AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from SET NOCOUNT ON; -- Variable deklarieren, dier der Cursor nutzt um hier seine ID rein zu schreiben DECLARE @CurrentID uniqueidentifier -- Deklariere Cursor, welcher Zeile für Zeile durchgeht... DECLARE DeleteCursor CURSOR FOR -- ...im folgenden Statement SELECT DISTINCT ID FROM deleted; OPEN DeleteCursor; -- Ein Cursor muss vorher geöffnet werden FETCH NEXT FROM DeleteCursor -- und der Zeiger (Cursor) auf die erste Zeile gezeigt werden INTO @CurrentID -- und schreibt die ID in die CurrentID Variable WHILE @@FETCH_STATUS = 0 -- Solange der Fetch_Status 0 ist, gibt es Datensätze. BEGIN -- -- die @CurrentID steht uns an dieser Stelle zur Verfügung DELETE FROM [Core].[ExampleTable] WHERE ID = @CurrentID FETCH NEXT FROM DeleteCursor INTO @CurrentID END CLOSE DeleteCursor; -- Der Cursor muss auch geschlossen werden DEALLOCATE DeleteCursor; -- und deallokiert. END |
Login