Erstellt einen Trigger für eine Tabelle.
CREATE [ OR REPLACE ] TRIGGER Triggername Triggertyp { Trigger-Ereignisliste | UPDATE OF Spaltenliste } [ ORDER Ganzzahl ] ON Tabellenname [ REFERENCING [ OLD AS alter_Name ] [ NEW AS neuer_Name ] [ REMOTE AS entfernter_Name ] ] [ FOR EACH { ROW | STATEMENT } ] [ WHEN ( Suchbedingung ) ] Trigger-Hauptteil
Spaltenliste : Spaltenname[, ...]
Triggertyp : BEFORE | AFTER | INSTEAD OF | RESOLVE
Trigger-Ereignisliste : Triggerereignis[, ... ]
Triggerereignis : DELETE | INSERT | UPDATE
Trigger-Hauptteil : eine BEGIN-Anweisung. Siehe BEGIN-Anweisung.
OR REPLACE-Klausel Wenn Sie OR REPLACE (CREATE OR REPLACE TRIGGER) angeben, wird ein neuer Trigger erstellt oder ein bestehender Trigger mit demselben Namen ersetzt.
Triggerereignis Trigger können durch die folgenden Ereignisse ausgelöst werden. Sie können mehrfache Trigger für DELETE-, INSERT- oder UPDATE-Ereignisse oder einen Trigger für das Ereignis UPDATE OF Spaltenliste festlegen:
DELETE-Klausel Wird jedes Mal aufgerufen, wenn eine Zeile in der zugeordneten Tabelle gelöscht wird.
INSERT-Klausel Wird jedes Mal aufgerufen, wenn eine neue Zeile in die dem Trigger zugeordnete Tabelle eingefügt wird.
UPDATE-Klausel Wird jedes Mal aufgerufen, wenn eine Zeile in der zugeordneten Tabelle aktualisiert wird.
UPDATE OF Spaltenliste-Klausel Wird jedes Mal aufgerufen, wenn eine Zeile der zugeordneten Tabelle aktualisiert und eine Spalte in Spaltenliste geändert wird. Dieser Typ eines Triggerereignisses kann nicht in einer Trigger-Ereignisliste verwendet werden. Es muss sich um das einzige für den Trigger definierte Ereignis handeln. Diese Klausel darf nicht in einem INSTEAD OF-Trigger verwendet werden.
Sie können unterschiedliche Trigger für jedes zu behandelnde Ereignis schreiben. Wenn Sie einige gemeinsame Aktionen und von einem Ereignis abhängige Aktionen verwenden, können Sie auch einen Trigger für alle Ereignisse erstellen und eine IF-Anweisung zur Unterscheidung der einzelnen durchgeführten Aktionen einsetzen Weitere Hinweise zu Triggervorgängen finden Sie unter Bedingungen für den Triggervorgang.
Triggertyp Trigger auf Zeilenebene können so definiert werden, dass sie vor (BEFORE), nach (AFTER) oder als Ersatz für (INSTEAD OF) einen Einfügungs-, Aktualisierungs- oder Löschvorgang ausgeführt werden. Trigger auf Anweisungsebene können so definiert werden, dass sie als Ersatz für (INSTEAD OF) oder nach (AFTER) der Anweisung ausgeführt werden.
BEFORE UPDATE-Trigger werden jedes Mal ausgelöst, wenn eine UPDATE-Anweisung für eine Zeile ausgeführt wird, ganz gleich, ob sich der neue Wert vom alten unterscheidet. Das heißt: Wenn eine Spaltenliste für einen BEFORE UPDATE-Trigger eingegeben wurde, löst der Trigger aus, wenn eine der Spalten in der Spaltenliste in der SET-Klausel der UPDATE-Anweisung erscheint. Wenn eine Spaltenliste für einen AFTER UPDATE-Trigger angegeben wurde, wird der Trigger nur ausgelöst, wenn der Wert einer der Spalten in der Spaltenliste von der UPDATE-Anweisung geändert wird.
INSTEAD OF-Trigger sind die einzige Art von Triggern, die Sie für eine normale Ansicht definieren können. INSTEAD OF-Trigger ersetzen die Trigger-Aktion durch eine andere Aktion. Bei Auslösen eines INSTEAD OF-Triggers wird die Trigger-auslösende Aktion übersprungen und stattdessen die angegebene Aktion durchgeführt. INSTEAD OF-Trigger können auf Zeilen- oder Anweisungsebene definiert werden. Ein auf Anweisungsebene definierter INSTEAD OF-Trigger ersetzt die gesamte Anweisung, einschließlich aller Vorgänge auf Zeilenebene. Wenn ein INSTEAD OF-Trigger auf Anweisungsebene ausgelöst wird, werden als Folge dieser Anweisung keine Trigger auf Zeilenebene ausgelöst. Der Hauptteil des Triggers auf Anweisungsebene könnte jedoch andere Vorgänge durchführen, die wiederum bewirken könnten, dass andere Trigger auf Zeilenebene ausgelöst werden.
Wenn Sie einen INSTEAD OF-Trigger definieren, können Sie nicht die UPDATE OF Spaltenliste-Klausel, die ORDER-Klausel oder die WHEN-Klausel verwenden.
Weitere Hinweise zu den Fähigkeiten der INSTEAD OF-Trigger und zu ihren Einschränkungen finden Sie unter INSTEAD OF-Trigger.
Der Triggertyp RESOLVE wird mit SQL Remote verwendet: Er wird nur vor UPDATE oder UPDATE OF Spaltenliste auf Zeilenebene ausgelöst.
FOR EACH-Klausel Mit der FOR EACH ROW-Klausel können Sie einen Trigger als Trigger auf Zeilenebene deklarieren. Um einen Trigger auf Anweisungsebene zu deklarieren, können Sie entweder eine FOR EACH STATEMENT-Klausel verwenden oder die FOR EACH-Klausel weglassen. Aus Gründen der Übersichtlichkeit wird empfohlen, die FOR EACH STATEMENT-Klausel anzugeben, wenn Sie einen Trigger auf Anweisungsebene deklarieren.
ORDER-Klausel Wenn Sie zusätzliche Trigger desselben Typs (INSERT, UPDATE oder DELETE) definieren, die zu demselben Zeitpunkt auslösen sollen (BEFORE, AFTER oder RESOLVE), müssen Sie eine ORDER-Klausel angeben, um den Datenbankserver anzuweisen, in welcher Reihenfolge er die Trigger auslösen soll. Die Ordnungsnummern müssen bei Triggern desselben Typs, die zum gleichzeitigen Auslösen konfiguriert wurden, eindeutig sein. Wenn Sie eine Ordnungsnummer eingeben, die nicht eindeutig ist, wird ein Fehler zurückgegeben. Ordnungsnummern müssen nicht aufeinanderfolgend sein (Eingabe von 1, 12, 30 ist zulässig). Der Datenbankserver löst den Trigger mit der niedrigsten Ordnungsnummer zuerst aus.
Wenn Sie die ORDER-Klausel weglassen oder 0 angeben, weist der Datenbankserver die Ordnungsnummer 1 zu. Wenn allerdings ein anderer Trigger desselben Typs bereits auf 1 gesetzt ist, wird ein Fehler zurückgegeben.
Wenn Sie zusätzliche Trigger hinzufügen, müssen Sie unter Umständen die bestehenden Trigger desselben Typs für das Ereignis ändern, je nachdem, ob die Aktionen der Trigger miteinander interagieren. Wenn sie nicht interagieren, muss der neue Trigger einen ORDER-Wert haben, der höher als die vorhandenen Trigger ist. Wenn sie interagieren, müssen Sie überlegen, was die anderen Trigger tun, und gegebenenfalls die Reihenfolge ihres Auslösens ändern.
Die ORDER-Klausel wird für INSTEAD OF-Trigger nicht unterstützt, da nur ein INSTEAD OF-Trigger eines Typs (INSERT, UPDATE, DELETE) für eine Tabelle der Ansicht definiert werden kann.
REFERENCING-Klausel Mit den Klauseln REFERENCING OLD und REFERENCING NEW können Sie eingefügte, gelöschte oder aktualisierte Zeilen referenzieren. Bei dieser Klausel wird ein UPDATE wie ein Löschvorgang behandelt, dem ein Einfügevorgang folgt.
INSERT übernimmt die REFERENCING NEW-Klausel, welche die eine eingefügte Zeile darstellt. Es gibt keine REFERENCING OLD-Klausel.
DELETE übernimmt die REFERENCING OLD-Klausel, welche die gelöschte Zeile darstellt. Es gibt keine REFERENCING NEW-Klausel.
UPDATE übernimmt die REFERENCING OLD-Klausel, die die Zeile vor der Aktualisierung darstellt, sowie die REFERENCING NEW-Klausel, die die Zeile nach der Aktualisierung darstellt.
Die Bedeutung von REFERENCING OLD und REFERENCING NEW ist unterschiedlich, je nachdem, ob es sich um einen Trigger auf Zeilenebene oder auf Anweisungsebene handelt. Für Trigger auf Zeilenebene können Sie mit der REFERENCING OLD-Klausel Werte in einer Zeile vor einem Aktualisierungs- oder Löschvorgang referenzieren und mit der REFERENCING NEW-Klausel können Sie eingefügte oder aktualisierte Werte referenzieren. Die OLD- und NEW-Zeilen können in BEFORE- und AFTER-Trigger referenziert werden. Mit der REFERENCING NEW-Klausel können Sie die neue Zeile in einem BEFORE-Trigger ändern, bevor Einfügungs- oder Aktualisierungsvorgänge stattfinden.
Wenn Trigger auf Anweisungsebene verwendet werden, beziehen sich die Klauseln REFERENCING OLD und REFERENCING NEW auf deklarierte temporäre Tabellen, welche die alten und neuen Werte der Zeilen enthalten.
Die REFERENCING REMOTE-Klausel wird mit SQL Remote verwendet. Mit dieser Klausel können Sie die Werte in der VERIFY-Klausel einer UPDATE-Anweisung referenzieren. Sie sollte nur mit Trigger für RESOLVE UPDATE- oder RESOLVE UPDATE OF-Spaltenlisten verwendet werden.
WHEN-Klausel Der Trigger wird nur für Zeilen ausgelöst, in denen die Suchbedingung als "true" bewertet wird. Die WHEN-Klausel kann nur mit Trigger auf Zeilenebene verwendet werden. Diese Klausel darf nicht in einem INSTEAD OF-Trigger verwendet werden.
Trigger-Hauptteil Der Trigger-Hauptteil enthält die Aktionen, die ausgeführt werden, wenn das Trigger-auslösende Ereignis eintritt, und besteht aus einer BEGIN-Anweisung. Siehe BEGIN-Anweisung.
Sie können Bedingungen für die Triggervorgänge in die BEGIN-Anweisung aufnehmen. Bedingungen für Triggervorgänge steuern die Aktionen je nach dem Trigger-Ereignis, das den Trigger ausgelöst hat. Beispiel: Wenn der Trigger bei Aktualisierungen und Löschung auslösen soll, können Sie für diese beiden Bedingungen unterschiedliche Aktionen definieren. Weitere Hinweise zu Bedingungen für Triggervorgänge mit einem Beispiel finden Sie unter Bedingungen für den Triggervorgang.
Die CREATE TRIGGER-Anweisung erstellt einen Trigger, der einer Tabelle in der Datenbank zugeordnet ist, und speichert den Trigger in der Datenbank.
Sie können keinen Trigger für eine materialisierte Ansicht erstellen. Wenn Sie es versuchen, wird ein SQLE_INVALID_TRIGGER_MATVIEW-Fehler zurückgegeben.
Der Trigger wird entweder als Trigger auf Zeilenebene deklariert und vor oder nach Änderung jeder Zeile ausgeführt oder als Trigger auf Anweisungsebene deklariert und nach Abschluss der gesamten Trigger-auslösenden Anweisung ausgeführt.
Sie müssen über RESSOURCE-Datenbankberechtigungen und ALTER-Berechtigungen für die Tabelle verfügen, oder der Eigentümer der Tabelle sein bzw. DBA-Berechtigungen besitzen. CREATE TRIGGER setzt eine Tabellensperre auf die Tabelle und erfordert eine exklusive Verwendung der Tabelle.
Automatisches Festschreiben (Autocommit).
SQL/2008 CREATE TRIGGER ist Teil der optionalen SQL-Sprachenfunktion T211 (Basis-Triggerfähigkeit) des SQL/2008-Standards. ROW-Trigger sind die optionale SQL-Sprachenfunktion T212, INSTEAD OF-Trigger die optionale SQL-Sprachenfunktion T213.
Einige Funktionen von SQL Anywhere-Triggern sind Erweiterungen des Herstellers. Es handelt sich dabei um die folgenden:
Die optionale OR REPLACE-Syntax. Beim Ersetzen eines bestehenden Triggers wird die Autorisierung zur Erstellung der neuen Trigger-Instanz umgangen.
Die ORDER-Klausel. In SQL/2008 werden Trigger in der Reihenfolge ausgelöst, in der sie erstellt wurden.
RESOLVE-Trigger sind eine Erweiterung des Herstellers.
Transact-SQL ROW- und RESOLVE-Trigger werden von Adaptive Server Enterprise nicht unterstützt. Der Transact-SQL-Dialekt von SQL Anywhere bietet keine Unterstützung für INSTEAD OF-Trigger aus Transact-SQL, obwohl diese von Adaptive Server Enterprise unterstützt werden. Transact-SQL-Trigger werden mit einer anderen Syntax definiert (siehe CREATE TRIGGER-Anweisung [T-SQL]).
Mit diesem Beispiel wird ein Trigger auf Anweisungsebene erstellt. Sie müssen erst die Tabelle erstellen:
CREATE TABLE t0 ( id integer NOT NULL, times timestamp NULL DEFAULT current timestamp, remarks text NULL, PRIMARY KEY ( id ) ); |
Als Nächstes erstellen Sie einen Trigger auf Anweisungsebene für diese Tabelle:
CREATE TRIGGER myTrig AFTER INSERT ORDER 4 ON t0 REFERENCING NEW AS new_name FOR EACH STATEMENT BEGIN DECLARE @id1 INTEGER; DECLARE @times1 TIMESTAMP; DECLARE @remarks1 LONG VARCHAR; DECLARE @err_notfound EXCEPTION FOR SQLSTATE VALUE '02000'; //declare a cursor for table new_name DECLARE new1 CURSOR FOR SELECT id, times, remarks FROM new_name; OPEN new1; //Open the cursor, and get the value LoopGetRow: LOOP FETCH NEXT new1 INTO @id1, @times1,@remarks1; IF SQLSTATE = @err_notfound THEN LEAVE LoopGetRow END IF; //print the value or for other use PRINT (@remarks1); END LOOP LoopGetRow; CLOSE new1 END; |
Im folgenden Beispiel wird der Trigger MyTrig ersetzt, der im vorherigen Beispiel erstellt wurde.
CREATE OR REPLACE TRIGGER myTrig AFTER INSERT ORDER 4 ON t0 REFERENCING NEW AS new_name FOR EACH STATEMENT BEGIN FOR L1 AS new1 CURSOR FOR SELECT id, times, remarks FROM new_name; DO //print the value or for other use PRINT (@remarks1); END FOR; END; |
Das folgende Beispiel zeigt, wie Sie REFERENCING NEW in einem BEFORE UPDATE-Trigger verwenden können. Hier wird gewährleistet, dass die Postleitzahlen in der neuen Employees-Tabelle in Großbuchstaben geschrieben werden:
CREATE TRIGGER emp_upper_postal_code BEFORE UPDATE OF PostalCode ON Employees REFERENCING NEW AS new_emp FOR EACH ROW WHEN ( ISNUMERIC( new_emp.PostalCode ) = 0 ) BEGIN -- Ensure postal code is uppercase (employee might be -- in Canada where postal codes contain letters) SET new_emp.PostalCode = UPPER(new_emp.PostalCode) END; UPDATE Employees SET state='ON', PostalCode='n2x 4y7' WHERE EmployeeID=191; SELECT PostalCode FROM Employees WHERE EmployeeID = 191; |
Das folgende Beispiel zeigt, wie Sie REFERENCING OLD in einem BEFORE DELETE-Trigger verwenden können. Dieses Beispiel verhindert, dass ein Mitarbeiter aus der Tabelle "Employees" gelöscht wird, mit dem das Arbeitsverhältnis noch besteht.
CREATE TRIGGER TR_check_delete_employee BEFORE DELETE ON Employees REFERENCING OLD AS current_employees FOR EACH ROW /* WHEN( search_condition ) */ BEGIN IF current_employees.TerminationDate IS NULL THEN RAISERROR 30001 'You cannot delete an employee who has not been fired'; END IF; END; |
Das folgende Beispiel zeigt, wie Sie REFERENCING NEW und REFERENCING OLD in einem BEFORE UPDATE-Trigger verwenden können. Dieses Beispiel verhindert eine Gehaltsminderung bei einem Mitarbeiter.
CREATE TRIGGER TR_check_salary_decrease BEFORE UPDATE ON Employees REFERENCING OLD AS before_update NEW AS after_update FOR EACH ROW BEGIN IF after_update.salary < before_update.salary THEN RAISERROR 30002 'You cannot decrease a salary'; END IF; END; |
Das folgende Beispiel zeigt, wie Sie REFERENCING NEW und REFERENCING OLD in einem BEFORE UPDATE-Trigger verwenden können. Dieses Beispiel verhindert ebenfalls eine Gehaltsminderung bei einem Mitarbeiter. Der Trigger ist jedoch effizienter, weil er nur ausgelöst wird, wenn die salary-Spalte aktualisiert wird.
CREATE TRIGGER TR_check_salary_decrease_column BEFORE UPDATE OF Salary ON Employees REFERENCING OLD AS before_update NEW AS after_update FOR EACH ROW /* WHEN( search_condition ) */ BEGIN IF after_update.salary < before_update.salary THEN RAISERROR 30002 'You cannot decrease a salary'; End IF; END; |
Das folgende Beispiel zeigt, wie Sie REFERENCING NEW in einem BEFORE INSERT- und UPDATE-Trigger verwenden können. Es erstellt einen Trigger, der ausgelöst wird, bevor eine Zeile in der SalesOrderItems-Tabelle eingefügt oder aktualisiert wird.
CREATE TRIGGER TR_update_date BEFORE INSERT, UPDATE ON SalesOrderItems REFERENCING NEW AS new_row FOR EACH ROW BEGIN SET new_row.ShipDate = CURRENT TIMESTAMP; END; |
![]() |
Kommentieren Sie diese Seite in DocCommentXchange.
|
Copyright © 2010, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.0 |