Firebird Documentation IndexFirebird 2.5 SprachreferenzStatements der Data Definition (DDL) → TRIGGER
Firebird Home Firebird Home Zurück: VIEWFirebird Documentation IndexNach oben: Statements der Data Definition (DDL)Weiter: PROCEDURE

TRIGGER

Inhaltsverzeichnis

CREATE TRIGGER
ALTER TRIGGER
CREATE OR ALTER TRIGGER
DROP TRIGGER
RECREATE TRIGGER

Ein Trigger ist ein spezieller Typ einer gespeicherten Prozedur, der nicht direkt aufgerufen wird, sondern ausgeführt wird, wenn ein bestimmtes Ereignis in der zugeordneten Tabelle oder Sicht (View) auftritt. Ein Trigger ist spezifisch für eine und nur eine Relation (Tabelle oder View) und eine Phase im Timing des Ereignisses (BEFORE oder AFTER). Es kann angegeben werden, dass dieser für ein bestimmtes Ereignis (Einfügen, Aktualisieren, Löschen) oder für eine Kombination von zwei oder drei dieser Ereignisse ausgeführt wird.

Eine andere Form eines Triggers - bekannt als ein „Datenbanktrigger“ - kann spezifiziert werden, um in Verbindung mit dem Start oder dem Ende einer Benutzersitzung (Verbindung) oder einer Benutzertransaktion zu ausgelöst zu werden.

CREATE TRIGGER

Benutzt für: Erstellen eines neuen Triggers

Verfügbar in: DSQL, ESQL

Syntax: 

CREATE TRIGGER trigname  {
  <relation_trigger_legacy> |
  <relation_trigger_sql2003> |
  <database_trigger> }
AS
	[<declarations>]
BEGIN
	[<PSQL_statements>]
END

<relation_trigger_legacy> ::=
  FOR {tablename | viewname}
  [ACTIVE | INACTIVE]
  {BEFORE | AFTER} <mutation_list>
  [POSITION number]

<relation_trigger_sql2003> ::=
  [ACTIVE | INACTIVE]
  {BEFORE | AFTER} <mutation_list>
  [POSITION number]
  ON {tablename | viewname}

<database_trigger> ::=
  [ACTIVE | INACTIVE] ON db_event [POSITION number]

<mutation_list> ::=
  <mutation> [OR <mutation> [OR <mutation>]]

<mutation> ::= { INSERT | UPDATE | DELETE }

<db_event> ::= {
  CONNECT |
  DISCONNECT |
  TRANSACTION START |
  TRANSACTION COMMIT |
  TRANSACTION ROLLBACK
}

<declarations> ::= {<declare_var> | <declare_cursor>};
  [{<declare_var> | <declare_cursor>}; …]
        

Tabelle 5.21. CREATE TRIGGER Statement-Parameter

Parameter Beschreibung
trigname Triggername bestehend aus bis zu 31 Zeichen. Dieser muss unter allen Triggernamen in der Datenbank eindeutig sein.
relation_trigger_legacy Legacy-Stil der Trigger-Deklaration für einen Relation-Trigger
relation_trigger_sql2003 Relation-Trigger-Deklaration gemäß dem SQL: 2003-Standard
database_trigger Datenbank-Triggerdeklaration
tablename Name der Tabelle, der der Relationstrigger zugeordnet ist
viewname Name der Sicht, der der Relationstrigger zugeordnet ist
mutation_list Liste von Relationsereignissen (Tabelle | Ansicht)
number Position des Triggers in der Zündreihenfolge. Von 0 bis 32.767
db_event Verbindungs- oder Transaktionsereignis
declarations Abschnitt zum Deklarieren von lokalen Variablen und benannten Cursorn
declare_var Lokale Variablendeklarieren
declare_cursor Benannte Cursor-Deklaration
PSQL_statements Anweisungen in der Programmiersprache von Firebird (PSQL)


Die Anweisung CREATE TRIGGER dient zum Erstellen eines neuen Triggers. Ein Trigger kann entweder für ein Ereignis Relation (Table | View) (oder eine Kombination von Ereignissen) oder für ein Datenbankereignis erstellt werden.

CREATE TRIGGER, zusammen mit den zugehörigen Assoziaten ALTER TRIGGER, CREATE ODER ALTER TRIGGER und RECREATE TRIGGER, ist eine zusammengesetzte Anweisung, bestehend aus einem Header und einem Rumpf. Der Header spezifiziert den Namen des Triggers, den Namen der Relation (für einen Relations-Trigger), die Phase des Triggers und das Ereignis, für das er gilt. Der Körper besteht aus optionalen Deklarationen von lokalen Variablen und benannten Cursors, gefolgt von einer oder mehreren Anweisungen oder Anweisungsblöcken, die alle in einem äußeren Block eingeschlossen sind, der mit dem Schlüsselwort BEGIN beginnt und mit dem Schlüsselwort END endet. Deklarationen und eingebettete Anweisungen werden mit Semikolons (;) abgeschlossen.

Der Name des Triggers muss unter allen Triggernamen eindeutig sein.

Statement-Terminatoren

Einige SQL-Anweisungseditoren - insbesondere das mit Firebird mitgelieferte Dienstprogramm isql und möglicherweise einige Editoren von Drittanbietern - verwenden eine interne Konvention, die erfordert, dass alle Anweisungen mit einem Semikolon abgeschlossen werden. Dies führt bei der Codierung in diesen Umgebungen zu einem Konflikt mit der PSQL-Syntax. Wenn Sie mit diesem Problem und seiner Lösung nicht vertraut sind, lesen Sie bitte die Details im Kapitel PSQL im Abschnitt Umschalten des Terminators in isql.

Relations-Trigger (auf Tabellen oder Views)

Relation-Trigger werden jedes Mal auf der Zeilen- (Datensatz-) Ebene ausgeführt, wenn sich das Zeilenbild ändert. Ein Trigger kann entweder ACTIVE oder INACTIVE sein. Nur aktive Trigger werden ausgeführt. Trigger werden standardmäßig mit ACTIVE erstellt.

Formen der Deklaration

Firebird unterstützt zwei Arten der Deklaration für Relationstrigger:

  • Die ursprüngliche Legacy-Syntax
  • Das standardmäßige SQL: 2003-Formular (empfohlen)

Das standardmäßige SQL: 2003-Formular ist das empfohlene Format.

Ein Relationstrigger spezifiziert unter anderem < eine Phase und ein oder mehrere Ereignisse.

Phase

Die Phase betrifft das Timing des Triggers in Bezug auf das Zustandswechselereignis in der Datenzeile:

  • Ein BEFORE-Trigger wird ausgelöst, bevor die angegebene Datenbankoperation (Einfügen, Aktualisieren oder Löschen) ausgeführt wird.
  • Ein AFTER-Trigger wird ausgeführt, nachdem die Datenbankoperation abgeschlossen wurde.

Multi-Aktions-Trigger

Eine Relationstriggerdefinition gibt mindestens eine der DML-Operationen INSERT, UPDATE und DELETE an, um ein oder mehrere Ereignisse anzuzeigen, auf die der Trigger ausgelöst werden soll. Wenn mehrere Operationen angegeben werden, müssen sie durch das Schlüsselwort OR getrennt werden. Keine Operation darf mehrmals auftreten.

Innerhalb des Anweisungsblocks werden die Booleschen Kontextvariablen INSERTING, UPDATING und DELETING verwendet, um die Art der derzeit ausgeführten Operation zu prüfen.

Ausführungsreihenfolge von Triggern

Das Schlüsselwort POSITION erlaubt es, eine optionale Ausführungsreihenfolge („firing order“) für eine Reihe von Triggern anzugeben, die dieselbe Phase und dasselbe Ereignis wie ihr Ziel haben. Die Standardposition ist 0. Wenn keine Positionen angegeben werden oder wenn mehrere Trigger eine einzelne Positionsnummer haben, werden die Trigger in der alphabetischen Reihenfolge ihrer Namen ausgeführt.

Variablendeklarationen

Der optionale Deklarationsabschnitt unter dem Schlüsselwort AS im Header des Triggers dient zum Definieren von Variablen und benannten Cursorn, die lokal zum Trigger gehören. Weitere Informationen finden Sie unter DECLARE VARIABLE und DECLARE CURSOR im Kapitel Prozedurales SQL.

Der Trigger-Body

Die lokalen Deklarationen (falls vorhanden) sind der letzte Teil des Headerabschnitts eines Triggers. Der Trigger-Body folgt, wobei ein oder mehrere Blöcke von PSQL-Anweisungen in einer Struktur eingeschlossen sind, die mit dem Schlüsselwort BEGIN beginnt und mit dem Schlüsselwort END endet.

Nur der Eigentümer der Sicht oder Tabelle und Administratoren haben die Berechtigung, CREATE TRIGGER zu verwenden.

Beispiele für CREATE TRIGGER für Tabellen und Views: 

  1. Erstellung eines Triggers in „Legacy“-Form. Wird vor dem Einfügen eines neuen Datensatzes in die Tabelle CUSTOMER ausgelöst.
    CREATE TRIGGER SET_CUST_NO FOR CUSTOMER
    ACTIVE BEFORE INSERT POSITION 0
    AS
    BEGIN
      IF (NEW.CUST_NO IS NULL) THEN
        NEW.CUST_NO = GEN_ID(CUST_NO_GEN, 1);
    END
                  
  2. Erstellen eines Triggers in SQL:2003-konformer Variante, der vor dem Einfügen eines neuen Datensatzes in die Tabelle CUSTOMER ausgelöst wird.
    CREATE TRIGGER set_cust_no
    ACTIVE BEFORE INSERT POSITION 0 ON customer
    AS
    BEGIN
      IF (NEW.cust_no IS NULL) THEN
        NEW.cust_no = GEN_ID(cust_no_gen, 1);
    END
                  
  3. Einen Trigger erstellen, der nach dem Einfügen, Aktualisieren oder Löschen eines Datensatzes in der Tabelle CUSTOMER ausgeführt wird.
    CREATE TRIGGER TR_CUST_LOG
    ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 10
    ON CUSTOMER
    AS
    BEGIN
      INSERT INTO CHANGE_LOG (LOG_ID,
                              ID_TABLE,
                              TABLE_NAME,
                              MUTATION)
      VALUES (NEXT VALUE FOR SEQ_CHANGE_LOG,
              OLD.CUST_NO,
              'CUSTOMER',
              CASE
                WHEN INSERTING THEN 'INSERT'
                WHEN UPDATING  THEN 'UPDATE'
                WHEN DELETING  THEN 'DELETE'
              END);
    END
                  

Datenbank-Trigger

Trigger können definiert werden, um auf „Datenbankereignisse“ zu reagieren. Dies können verschiedene Ereignisse sein. Diese können auf den Umfang einer Sitzung (Verbindung) hinweg agieren, aber auch über die Umgebung einer Transaktion wirken:

  • CONNECT
  • DISCONNECT
  • TRANSACTION START
  • TRANSACTION COMMIT
  • TRANSACTION ROLLBACK

Ausführung von Datenbanktriggern und Fehlerbehandlung

CONNECT- und DISCONNECT-Trigger werden in einer speziell für diesen Zweck erstellten Transaktion ausgeführt. Läuft alles glatt, wird die Transaktion committed. Nicht abgefangene Ausnahmen bewirken, dass die Transaktion zurückgesetzt wird, und

  • für einen CONNECT-Trigger wird die Verbindung unterbrochen und die Ausnahme wird an den Client zurückgegeben
  • für einen DISCONNECT-Trigger werden Ausnahmen nicht gemeldet. Die Verbindung ist wie beabsichtigt unterbrochen

TRANSACTION-Trigger werden innerhalb der Transaktion ausgeführt, deren Start, Commit oder Rollback sie hervorruft. Die Aktion, die nach einer nicht abgefangenen Ausnahme ausgeführt wird, hängt vom Ereignis ab:

  • In einem TRANSACTION START-Trigger wird die Ausnahme an den Client gemeldet und die Transaktion wird zurückgesetzt
  • In einem TRANSACTION COMMIT-Trigger wird die Ausnahme gemeldet, die bisherigen Aktionen des Triggers werden rückgängig gemacht und das Commit abgebrochen
  • In einem TRANSACTION ROLLBACK-Trigger wird die Ausnahme nicht gemeldet und die Transaktion wird wie beabsichtigt zurückgesetzt.

Fallen

Offensichtlich gibt es keine direkte Möglichkeit zu wissen, ob ein DISCONNECT- oder TRANSACTION ROLLBACK-Trigger eine Ausnahme verursacht hat. Daraus folgt auch, dass die Verbindung zur Datenbank nicht zustande kommen kann, wenn ein CONNECT-Trigger eine Ausnahme verursacht und eine Transaktion nicht gestartet werden kann, wenn auch ein TRANSACTION START-Trigger einen auslöst. Beide Phänomene sperrt Sie effektiv aus Ihrer Datenbank aus, bis Sie mit unterdrückten Datenbanktriggern zurückkehren und den fehlerhaften Code beheben.

Triggerunterdrückung

Einige Firebird-Befehlszeilentools wurden mit Switches ausgestattet, mit denen ein Administrator die automatische Auslösung von Datenbanktriggern unterdrücken kann. Bisher sind sie:

gbak -nodbtriggers
isql -nodbtriggers
nbackup -T
                

Zwei-Phasen Commit

In einem zweiphasigen Commit-Szenario löst ein TRANSACTION COMMIT-Trigger bereits in der Vorbereitungsphase aus und nicht erst beim Commit.

Einige Vorbehalte
  1. Die Verwendung der Anweisung IN AUTONOMOUS TRANSACTION DO in den Datenbanktriggern für Transaktionen (TRANSACTION START, TRANSACTION ROLLBACK, TRANSACTION COMMIT) kann dazu führen, dass die autonome Transaktion eine Endlosschleife generiert
  2. Die Ereignistrigger DISCONNECT und TRANSACTION ROLLBACK werden nicht ausgeführt, wenn Clients über Überwachungstabellen getrennt werden (DELETE FROM MON$ATTACHMENTS)

Nur der Datenbankbesitzer und Administratoren haben die Berechtigung zum Erstellen von Datenbanktriggern.

Beispiele für CREATE TRIGGER für „Database Triggers“: 

  1. Einen Trigger für das Ereignis erstellen, bei dem eine Verbindung zur Datenbank hergestellt wird, in der Benutzer protokolliert werden, die sich am System anmelden. Der Trigger wird als inaktiv erstellt.
    CREATE TRIGGER tr_log_connect
    INACTIVE ON CONNECT POSITION 0
    AS
    BEGIN
      INSERT INTO LOG_CONNECT (ID,
                               USERNAME,
                               ATIME)
      VALUES (NEXT VALUE FOR SEQ_LOG_CONNECT,
              CURRENT_USER,
              CURRENT_TIMESTAMP);
    END
                  
  2. Einen Trigger für das Ereignis der Verbindung mit der Datenbank erstellen, das es keinem Benutzer, außer SYSDBA, erlaubt, sich außerhalb der Geschäftszeiten anzumelden.
    CREATE EXCEPTION E_INCORRECT_WORKTIME 'The working day has not started yet.';
    
    CREATE TRIGGER TR_LIMIT_WORKTIME ACTIVE
    ON CONNECT POSITION 1
    AS
    BEGIN
      IF ((CURRENT_USER <> 'SYSDBA') AND
          NOT (CURRENT_TIME BETWEEN time '9:00' AND time '17:00')) THEN
         EXCEPTION E_INCORRECT_WORKTIME;
    END
                  

Siehe auch:  ALTER TRIGGER, CREATE OR ALTER TRIGGER, RECREATE TRIGGER, DROP TRIGGER

ALTER TRIGGER

Benutzt für: Ändern und Deaktivieren eines vorhandenen Triggers

Verfügbar in: DSQL, ESQL

Syntax: 

ALTER TRIGGER trigname
[ACTIVE | INACTIVE]
[{BEFORE | AFTER} <mutation_list> | ON db_event]
[POSITION number]
[
 AS
  [<declarations>]
	 BEGIN
    [<PSQL_statements>]
	 END
]

<mutation_list> ::=
  <mutation> [OR <mutation> [OR <mutation>]]

<mutation> ::= { INSERT | UPDATE | DELETE }

<db_event> ::= {
  CONNECT |
  DISCONNECT |
  TRANSACTION START |
  TRANSACTION COMMIT |
  TRANSACTION ROLLBACK
}

<declarations> ::= {<declare_var> | <declare_cursor>};
	[{<declare_var> | <declare_cursor>}; …]
        

Tabelle 5.22. ALTER TRIGGER Statement-Parameter

Parameter Beschreibung
trigname Name eines vorhandenen Triggers
mutation_list Liste von Relation-Ereignissen (Tabelle | Ansicht)
number Position des Triggers in der Zündreihenfolge. Von 0 bis 32.767
declarations Abschnitt zum Deklarieren von lokalen Variablen und benannter Cursor
declare_var Lokale Variablendeklaration
declare_cursor Benannte Cursor-Deklaration
PSQL_statements Anweisungen in der Programmiersprache von Firebird (PSQL)


Die Anweisung ALTER TRIGGER erlaubt bestimmte Änderungen am Header und am Rumpf eines Triggers.

Zulässige Änderungen an Triggern

  • Status (ACTIVE | INACTIVE)
  • Phase (BEFORE | AFTER)
  • Veranstaltungen; aber Relationstriggerereignisse können nicht in Datenbanktriggerereignisse geändert werden, und umgekehrt
  • Position innerhalb der Ausführungsreihenfolge
  • Änderungen am Code im Trigger-Body

Wenn ein Element nicht angegeben wurde, bleibt es unverändert.

Zur Erinnerungen

Das BEFORE-Schlüsselwort weist darauf hin, dass der Trigger ausgeführt wird, bevor das zugehörige Ereignis eintritt. Das Schlüsselwort AFTER weist darauf hin, dass es nach dem Ereignis ausgeführt wird.

Mehr als ein Beziehungsereignis - INSERT, UPDATE, DELETE - kann mit einem einzigen Trigger abgedeckt werden. Die Ereignisse sollten mit dem Schlüsselwort OR getrennt werden. Kein Ereignis sollte mehr als einmal erwähnt werden.

Das Schlüsselwort POSITION erlaubt es, eine optionale Ausführungsreihenfolge („firing order“) für eine Reihe von Triggern anzugeben, die dieselbe Phase und dasselbe Ereignis wie ihr Ziel haben. Die Standardposition ist 0. Wenn keine Positionen angegeben werden oder wenn mehrere Trigger eine einzelne Positionsnummer haben, werden die Trigger in der alphabetischen Reihenfolge ihrer Namen ausgeführt.

Administratoren und folgende Benutzer haben die Berechtigung für die Ausführung von ALTER TRIGGER:

  • Für Relations-Trigger der Besitzer des Tisches
  • Für Datenbank-Trigger der Eigentümer der Datenbank

Beispiele mit ALTER TRIGGER: 

  1. Deaktivieren des Triggers set_cust_no (Umschalten in den inaktiven Status)
    ALTER TRIGGER set_cust_no INACTIVE;
                
  2. Ändern der Ausführungsreihenfolge des Triggers set_cust_no.
    ALTER TRIGGER set_cust_no POSITION 14;
                
  3. Den Trigger TR_CUST_LOG in den inaktiven Status schalten und die Liste der Ereignisse ändern.
    ALTER TRIGGER TR_CUST_LOG
    INACTIVE AFTER INSERT OR UPDATE;
                
  4. Den tr_log_connect-Trigger in den aktiven Status schalten und seine Position und seinen Körper ändern.
    ALTER TRIGGER tr_log_connect
    ACTIVE POSITION 1
    AS
    BEGIN
      INSERT INTO LOG_CONNECT (ID,
                               USERNAME,
                               ROLENAME,
                               ATIME)
      VALUES (NEXT VALUE FOR SEQ_LOG_CONNECT,
              CURRENT_USER,
              CURRENT_ROLE,
              CURRENT_TIMESTAMP);
    END
                

Siehe auch:  CREATE TRIGGER, CREATE OR ALTER TRIGGER, RECREATE TRIGGER, DROP TRIGGER

CREATE OR ALTER TRIGGER

Benutzt für:  Erstellen eines neuen Triggers oder Ändern eines vorhandenen Triggers

Verfügbar in: DSQL

Syntax: 

CREATE OR ALTER TRIGGER trigname  {
  <relation_trigger_legacy> |
  <relation_trigger_sql2003> |
  <database_trigger> }
AS
[<declarations>]
BEGIN
[<PSQL_statements>]
END
        

Für das vollständige Detail der Syntax siehe CREATE TRIGGER .

Die Anweisung CREATE OR ALTER TRIGGER erstellt einen neuen Trigger, falls er nicht existiert. Andernfalls ändert und kompiliert er es erneut, wobei die Privilegien intakt und die Abhängigkeiten unberührt bleiben.

Beispiel mit CREATE OR ALTER TRIGGER:  Erstellen eines neuen Triggers, falls er nicht existiert oder anpassen, falls vorhanden.

CREATE OR ALTER TRIGGER set_cust_no
ACTIVE BEFORE INSERT POSITION 0 ON customer
AS
BEGIN
  IF (NEW.cust_no IS NULL) THEN
    NEW.cust_no = GEN_ID(cust_no_gen, 1);
END
          

Siehe auch:  CREATE TRIGGER, ALTER TRIGGER, RECREATE TRIGGER

DROP TRIGGER

Benutzt für:  Einen vorhandenen Trigger löschen

Verfügbar in: DSQL, ESQL

Syntax: 

DROP TRIGGER trigname
        

Tabelle 5.23. DROP TRIGGER Statement-Parameter

Parameter Beschreibung
trigname Triggername


Die Anweisung DROP TRIGGER löscht einen vorhandenen Trigger.

Administrators und die folgenden Benutzer besitzen die Berechtigung, die Anweisung DROP TRIGGER auszuführen:

  • Für Relations-Trigger, der Eigentümer der Tabelle
  • Für Datenbank-Trigger, der Eigentümer der Datenbank

Beispiele für DROP TRIGGER:  Löschen des Triggers set_cust_no.

DROP TRIGGER set_cust_no;
          

Siehe auch:  CREATE TRIGGER, RECREATE TRIGGER

RECREATE TRIGGER

Benutzt für:  Erstellen eines neuen Triggers oder Neuerstellung eines vorhandenen

Verfügbar in: DSQL

Syntax: 

RECREATE TRIGGER trigname {
  <relation_trigger_legacy> | 
  <relation_trigger_sql2003> | 
  <database_trigger> }
AS
[<declarations>]
BEGIN
[<PSQL_statements>]
END
        

Für die detaillierte Syntax, vergleichen Sie CREATE TRIGGER .

Die Anweisung RECREATE TRIGGER erzeugt einen neuen Trigger, wenn kein Trigger mit dem angegebenen Namen existiert. Andernfalls versucht die Anweisung RECREATE TRIGGER, den vorhandenen Trigger zu löschen und einen neuen zu erstellen. Die Operation schlägt beim COMMIT fehl, wenn Triggerabhängigkeiten vorliegen.

Warnung

Beachten Sie, dass Abhängigkeitsfehler erst in der Phase COMMIT dieser Operation erkannt werden.

Beispiele für RECREATE TRIGGER:  Erstellen oder Neuerstellung des Triggers set_cust_no.

RECREATE TRIGGER set_cust_no
ACTIVE BEFORE INSERT POSITION 0 ON customer
AS
BEGIN
  IF (NEW.cust_no IS NULL) THEN
    NEW.cust_no = GEN_ID(cust_no_gen, 1);
END
          

Siehe auch:  CREATE TRIGGER, DROP TRIGGER, CREATE OR ALTER TRIGGER

Zurück: VIEWFirebird Documentation IndexNach oben: Statements der Data Definition (DDL)Weiter: PROCEDURE
Firebird Documentation IndexFirebird 2.5 SprachreferenzStatements der Data Definition (DDL) → TRIGGER