Sonntag, 7. September 2008

entwickler.com Magazine Konferenzen Akademie Entwickler-Forum Jobbörse Bücher
Software & Support Verlag

Einsatz eines INSTEAD OF DELETE-Triggers

Frage: Ich möchte das Löschen eines Datensatzes verhindern, wenn ein Feld einen bestimmten Wert enthält. Mein erster Gedanke war an eine Stored Procedure, aber was passiert, wenn der Benutzer nicht die Procedure benutzt? Mein nächster Gedanke war ein Trigger, beim Microsoft SQL Server also ein INSTEAD OF DELETE-Trigger. Aber wie verhindere ich das Löschen, bzw. wie bekomme ich den Datensatz aus der deleted-Tabelle?

Antwort: Wenn der Benutzer nur Rechte für das Ausführen der Stored Procedure besitzt, aber keine Rechte an der Basistabelle, kann es nicht zu Problemen kommen. Daher wäre das Auslagern dieser Prüfung in eine Stored Procedure der saubere Weg.

Allerdings kann auch der INSTEAD OF DELETE-Trigger genutzt werden. Der Microsoft SQL Server unterscheidet sich beim Thema Trigger vom den anderen SQL-Datenbanken. Es gibt beim MS SQL Server zwei Arten von Triggern. Die normalen Trigger sind alle After-Trigger, die erst nach der eigentlichen Aktion (UPDATE, INSERT oder DELETE) ausgelöst werden. Wenn aber Spaltenwerte vor dem UPDATE-Schreibvorgang auf die Tabelle vom Trigger ausgetauscht werden sollen oder wenn bestimmte Datensätze erst gar nicht gelöscht werden sollen, muss man zum INSTEAD OF-Trigger greifen. Beim MS SQL Server sind im Trigger zwei Hilfstabellen sichtbar. Die Tabelle Inserted enthält die neu hinzugekommenen bzw. geänderten Datensätze, während die Tabelle Deleted die gelöschten Datensätze enthält. Im Fall des INSTEAD OF-Trigger verschiebt sich die Bedeutung dieser beiden Hilfstabellen etwas, denn in diesem Fall stehen dort nur die im Trigger noch zu erledigenden Aufgaben. Das folgende Beispiel demonstriert diesen Fall:

1. Es wird in der MS SQL Server-Datenbank tempdb eine Tabelle angelegt
2. Die Tabelle wird mit Testdatensätzen gefüllt
3. Es wird ein INSTEAD OF DELETE-Trigger für diese Tabelle aktiviert
4. Die DELETE-Anweisung löscht "alle" Datensätze aus dieser Tabelle
5. Der INSTEAD OF DELETE-Trigger löscht allerdings nur die Datensätze, bei denen in der Spalte Wert nicht ein bestimmter Wert vorkommt.

USE tempdb
GO

CREATE TABLE TriggerDemo ( RecID INTEGER NOT NULL IDENTITY PRIMARY KEY, Wert VARCHAR(9) NOT NULL ) GO INSERT INTO TriggerDemo (Wert) VALUES ('A') INSERT INTO TriggerDemo (Wert) VALUES ('B') INSERT INTO TriggerDemo (Wert) VALUES ('C') INSERT INTO TriggerDemo (Wert) VALUES ('D') GO
CREATE TRIGGER trDEL_TriggerDemo ON TriggerDemo INSTEAD OF DELETE AS BEGIN DELETE FROM TriggerDemo WHERE RecID IN (SELECT RecID FROM deleted WHERE Wert <> 'C') END GO
-- Trigger testen DELETE FROM TriggerDemo
Ergebnis der letzten SELECT-Abfrage: Der Datensatz mit dem Wert C in der Spalte Wert wurde nicht gelöscht.
RecID       Wert      
----------- --------- 
3           C

(1 row(s) affected)






Software & Support Verlag GmbH