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-Benutzerhandbuch » Gespeicherte Prozeduren und Trigger » Prozeduren, Trigger und Batches verwenden » Einführung in Trigger » Erweiterte Informationen zu Triggern

 

INSTEAD OF-Trigger

INSTEAD OF-Trigger unterscheiden sich von BEFORE- und AFTER-Triggern, da beim Auslösen eines INSTEAD OF-Triggers die auslösende Aktion übersprungen wird und stattdessen die festgelegte Aktion durchgeführt wird.

Die folgende Liste zeigt die Fähigkeiten und Einschränkungen, die speziell für INSTEAD OF-Trigger gelten:

  • Für jedes Trigger-Ereignis in einer bestimmten Tabelle kann es nur einen einzigen INSTEAD OF-Trigger geben.

  • INSTEAD OF-Trigger können für eine Tabelle oder eine Ansicht definiert werden. INSTEAD OF-Trigger können jedoch nicht für materialisierte Ansichten definiert werden, da Sie für diese keine DML-Vorgänge ausführen können wie etwa die Anweisungen INSERT, DELETE und UPDATE.

  • Wenn Sie einen INSTEAD OF-Trigger definieren, können Sie keine ORDER- oder WHEN-Klauseln angeben.

  • Für das Trigger-Ereignis UPDATE OF Spaltenliste können Sie keinen INSTEAD OF-Trigger definieren. Weitere Hinweise finden Sie unter CREATE TRIGGER-Anweisung.

  • Ob ein INSTEAD OF-Trigger Rekursionen ausführt, hängt davon ab, ob das Ziel des Triggers eine Basistabelle oder eine Ansicht ist. Die Rekursion ist für Ansichten möglich, nicht aber für Basistabellen. D.h., wenn ein INSTEAD OF-Trigger DML-Vorgänge in der Basistabelle durchführt, für die der Trigger definiert ist, werden durch diese Vorgänge keine Trigger ausgelöst (auch keine BEFORE- oder AFTER-Trigger). Falls es sich beim Ziel um eine Ansicht handelt, werden alle Trigger für die Vorgänge ausgelöst, die für die Ansicht ausgeführt werden.

  • Wenn ein INSTEAD OF-Trigger für eine Tabelle definiert ist, können Sie in dieser Tabelle keine INSERT-Anweisung mit einer ON EXISTING-Klausel ausführen. Falls Sie dies doch versuchen, wird der Fehler SQLE_INSTEAD_TRIGGER gemeldet.

  • Sie können keine INSERT-Anweisung für eine Ansicht ausführen, die mit WITH CHECK OPTION definiert wurde (oder die in einer anderen Ansicht verschachtelt ist, die auf diese Art definiert wurde) und für die ein INSTEAD OF INSERT-Trigger definiert ist. Dies gilt auch für die Anweisungen UPDATE und DELETE. Falls Sie dies doch versuchen, wird der Fehler SQLE_CHECK_TRIGGER_CONFLICT gemeldet.

  • Falls ein INSTEAD OF-Trigger als Ergebnis einer positionsbasierten UPDATE-, DELETE- oder PUT-Anweisung oder einer breiten Einfügung ausgelöst wird, wird der Fehler SQLE_INSTEAD_TRIGGER_POSITIONED gemeldet.

Nicht aktualisierbare Ansichten mit INSTEAD OF-Trigger aktualisieren

INSTEAD OF-Trigger ermöglichen es Ihnen, die Anweisungen INSERT, UPDATE oder DELETE auf Ansichten anzuwenden, die normalerweise nicht aktualisierbar sind. Der Hauptteil des Triggers definiert, was die Ausführung der entsprechenden INSERT-, UPDATE- oder DELETE-Anweisung bedeutet. Angenommen, Sie erstellen den folgenden Index:

CREATE VIEW V1 ( Surname, GivenName, State ) 
   AS SELECT DISTINCT Surname, GivenName, State 
        FROM Contacts;

Sie können keine Zeilen aus V1 löschen, da das Schlüsselwort DISTINCT dazu führt, dass V1 nicht aktualisierbar ist. In anderen Worten, der Datenbankserver kann nicht eindeutig ermitteln, was es bedeutet, eine Zeile aus V1 zu löschen. Sie könnten jedoch einen INSTEAD OF DELETE-Trigger definieren, der einen Löschvorgang in V1 durchführt. Der folgende Trigger löscht beispielsweise alle Zeilen mit einem bestimmten "Surname", "GivenName" und "State" aus "Contacts", wenn diese Zeile aus V1 gelöscht wird:

CREATE TRIGGER V1_Delete
  INSTEAD OF DELETE ON V1
  REFERENCING OLD AS old_row
  FOR EACH ROW
BEGIN
    DELETE FROM Contacts
      WHERE Surname = old_row.Surname
        AND GivenName = old_row.GivenName
        AND State = old_row.State
END;

Wenn der Trigger "V1_Delete" definiert ist, können Sie Zeilen aus V1 löschen. Sie können auch andere INSTEAD OF-Trigger festlegen, um INSERT- und UPDATE-Anweisungen auf V1 zu ermöglichen.

Falls eine Ansicht mit einem INSTEAD OF DELETE-Trigger in einer anderen Ansicht verschachtelt ist, wird sie zum Prüfen der Aktualisierbarkeit durch DELETE wie eine Basistabelle behandelt. Dies trifft auch für INSERT- und UPDATE-Vorgänge zu. Um das vorherige Beispiel fortzuführen, erstellen Sie nun eine andere Ansicht:

CREATE VIEW V2 ( Surname, GivenName ) AS
  SELECT Surname, GivenName from V1;

Ohne den Trigger "V1_Delete" können Sie keine Zeilen aus V2 löschen, weil V1 normalerweise nicht aktualisierbar ist, und das Gleiche gilt für V2. Wenn Sie allerdings einen INSTEAD OF DELETE-Trigger auf V1 definieren, können Sie Zeilen aus V2 löschen. Jede aus V2 gelöschte Zeile führt zum Löschen einer Zeile aus V1, wodurch der Trigger "V1_Delete" ausgelöst wird.

Seien Sie bei der Definition eines INSTEAD OF-Triggers auf einer verschachtelten Ansicht vorsichtig, da das Auslösen des Triggers unvorhersehbare Konsequenzen haben kann. Um das gewünschte Verhalten explizit anzugeben, definieren Sie den INSTEAD OF-Trigger für jede Ansicht, die die verschachtelte Ansicht referenziert.

Der folgende Trigger könnte für V2 definiert werden, um das gewünschte Verhalten für eine DELETE-Anweisung zu bewirken:

CREATE TRIGGER V2_Delete
  INSTEAD OF DELETE ON V2
  REFERENCING OLD AS old_row
  FOR EACH ROW
BEGIN
    DELETE FROM Contacts
      WHERE Surname = old_row.Surname
        AND GivenName = old_row.GivenName
END;

Der Trigger "V2_Delete" sorgt dafür, dass das Verhalten eines Löschvorgangs auf V2 unverändert bleibt, sogar wenn der INSTEAD OF DELETE-Trigger für V1 gelöscht oder geändert wird.