Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (Deutsch) » SQL Anywhere Server - SQL-Referenzhandbuch » Verwendung von SQL » SQL-Anweisungen » SQL-Anweisungen (A-D)

 

CREATE TRIGGER-Anweisung

Mit dieser Anweisung erstellen Sie einen Trigger für eine Tabelle.

Syntax
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. Weitere Hinweise finden Sie unter BEGIN-Anweisung.

Parameter
  • 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.

  • Trigger_Ereignis   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   Wird jedes Mal aufgerufen, wenn eine Zeile in der zugeordneten Tabelle gelöscht wird.

    • INSERT   Wird jedes Mal aufgerufen, wenn eine neue Zeile in die dem Trigger zugeordnete Tabelle eingefügt wird.

    • UPDATE   Wird jedes Mal aufgerufen, wenn eine Zeile in der zugeordneten Tabelle aktualisiert wird.

    • UPDATE OF Spaltenliste   Wird jedes Mal aufgerufen, wenn eine Zeile der zugeordneten Tabelle aktualisiert und eine Spalte in Spaltenliste geändert wird. Dieser Typ eines Trigger-Ereignisses kann nicht in einer Trigger_Ereignisliste verwendet werden. Es muss das einzige für den Trigger definierte Ereignis sein. 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-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 abä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 einer Aktualisierung oder einer Löschung 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 Standardnamen für diese Tabellen lauten deleted und inserted.

    Die REFERENCING REMOTE-Klausel wird mit SQL Remote verwendet. Mit dieser Klausel können Sie sich auf Werte in der VERIFY-Klausel einer UPDATE-Anweisung beziehen. 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-Rumpf enthält die Aktionen, die ausgeführt werden, wenn das Trigger-auslösende Ereignis eintritt, und besteht aus einer BEGIN-Anweisung. Weitere Hinweise finden Sie unter 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.

Bemerkungen

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.

Berechtigungen

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.

Nebenwirkungen

Automatisches Festschreiben (Autocommit).

Siehe auch
Standards und Kompatibilität
  • SQL/2003   Persistent Stored Module-Funktion. Bei einigen Klauseln handelt es sich um Erweiterungen des Herstellers.

Beispiel

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;

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;