Firebird Documentation IndexFirebird 2.5 SprachreferenzProzedurale SQL-Anweisungen (PSQL) → Schreiben des Body-Codes
Firebird Home Firebird Home Zurück: TriggerFirebird Documentation IndexNach oben: Prozedurale SQL-Anweisungen (PSQL)Weiter: Abfangen und Behandeln von Fehlern

Schreiben des Body-Codes

Inhaltsverzeichnis

Zuweisungs-Statements
DECLARE CURSOR
DECLARE VARIABLE
BEGIN ... END
IF ... THEN ... ELSE
WHILE ... DO
LEAVE
EXIT
SUSPEND
EXECUTE STATEMENT
FOR SELECT
FOR EXECUTE STATEMENT
OPEN
FETCH
CLOSE
IN AUTONOMOUS TRANSACTION
POST_EVENT

In diesem Abschnitt werden die prozeduralen SQL-Sprachkonstrukte und -Anweisungen näher betrachtet, die zum Codieren des Rumpfs einer gespeicherten Prozedur, eines Triggers oder eines anonymen PSQL-Blocks verfügbar sind.

Zuweisungs-Statements

Verwendet für:  Zuweisen eines Werts zu einer Variablen

Verfügbar in:  PSQL

Syntax: 

varname = <value_expr>
        

Tabelle 7.3. Zuweisungs-Statement-Parameter

Argument Beschreibung
varname Name eines Parameters oder einer lokalen Variablen
value_expr Ein Ausdruck, eine Konstante oder eine Variable, dessen Wert in den gleichen Datentyp wie <varname>


PSQL verwendet das Äquivalenzsymbol (=) als Zuweisungsoperator. Die Zuweisungsanweisung weist der Variablen links vom Operator den rechten SQL-Ausdruckswert zu. Der Ausdruck kann ein beliebiger gültiger SQL-Ausdruck sein: Er kann Literale, interne Variablennamen, Arithmetik-, logische und Zeichenfolgenoperationen, Aufrufe von internen Funktionen oder externe Funktionen (UDFs) enthalten.

Beispiel mit Zuweisungsanweisungen: 

CREATE PROCEDURE MYPROC (
    a INTEGER,
    b INTEGER,
    name VARCHAR (30)
)
RETURNS (
    c INTEGER,
    str VARCHAR(100))
AS
BEGIN
  -- assigning a constant
  c = 0;
  str = '';
  SUSPEND;
  -- assigning expression values
  c = a + b;
  str = name || CAST(b AS VARCHAR(10));
  SUSPEND;
  -- assigning expression value
  -- built by a query
  c = (SELECT 1 FROM rdb$database);
  -- assigning a value from a context variable
  str = CURRENT_USER;
  SUSPEND;
END
        

Siehe auch:  DECLARE VARIABLE

DECLARE CURSOR

Verwendet für:  Deklarieren eines benannten Cursors

Verfügbar in:  PSQL

Syntax: 

DECLARE [VARIABLE] cursorname CURSOR FOR (<select>) [FOR UPDATE]
        

Tabelle 7.4. DECLARE CURSOR-Statement-Parameter

Argument Beschreibung
cursorname Name des Cursors
select SELECT-Statement


Die Anweisung DECLARE CURSOR ... FOR bindet einen benannten Cursor an die Ergebnismenge, die in der in der Klausel FOR angegebenen SELECT-Anweisung ermittelt wurde. Im Body-Code kann der Cursor geöffnet werden, um zeilenweise durch die Ergebnismenge zu gehen und zu schließen. Während der Cursor geöffnet ist, kann der Code positionierte Aktualisierungen und Löschungen unter Verwendung der Anweisung WHERE CURRENT OF für UPDATE oder DELETE durchführen.

Cursor-Idiosynkrasien

  • Die optionale Klausel FOR UPDATE kann in der SELECT-Anweisung enthalten sein, ihre Abwesenheit verhindert jedoch nicht die erfolgreiche Ausführung einer positionierten Aktualisierung oder Löschung.

  • Es sollte darauf geachtet werden, dass die Namen von deklarierten Cursorn nicht mit Namen in Konflikt geraten, die später in Anweisungen für AS CURSOR-Klauseln verwendet werden.

  • Wenn der Cursor nur zum Durchlaufen der Ergebnismenge benötigt wird, ist es fast immer einfacher und weniger fehleranfällig, eine Anweisung FOR SELECT mit der Klausel AS CURSOR zu verwenden. Deklarierte Cursor müssen zum Abrufen von Daten explizit geöffnet und geschlossen werden. Die Kontextvariable ROW_COUNT muss nach jedem Abruf überprüft werden. Wenn der Wert Null ist, muss die Schleife beendet werden. Eine FOR SELECT-Anweisung überprüft dies automatisch.

    Dennoch bieten deklarierte Cursor ein hohes Maß an Kontrolle über sequentielle Ereignisse und ermöglichen die parallele Verwaltung mehrerer Cursor.

  • Das SELECT-Statement kann Parameter enthalten. Zum Beispiel:

    SELECT NAME || :SFX FROM NAMES WHERE NUMBER = :NUM
                  

    Jeder Parameter muss zuvor als PSQL-Variable deklariert worden sein, auch wenn sie als Ein- und Ausgabeparameter entstehen. Wenn der Cursor geöffnet wird, wird dem Parameter der aktuelle Wert der Variablen zugewiesen.

Achtung!

Wenn sich der Wert einer PSQL-Variablen, die in der SELECT-Anweisung verwendet wird, während der Schleife ändert, kann der neue Wert (jedoch nicht immer) für die verbleibenden Zeilen verwendet werden. Es ist besser, solche Situationen nicht unbeabsichtigt entstehen zu lassen. Wenn Sie dieses Verhalten wirklich benötigen, sollten Sie Ihren Code sorgfältig testen, um sicherzustellen, dass Sie genau wissen, wie sich Änderungen in der Variablen auf das Ergebnis auswirken.

Beachten Sie besonders, dass das Verhalten möglicherweise vom Abfrageplan abhängt, insbesondere von den verwendeten Indizes. Es gibt derzeit keine strengen Regeln für solche Situationen, aber das könnte sich in zukünftigen Versionen von Firebird ändern.

Beispiel für benannte Cursor

  1. Declaring a named cursor in the trigger.
    CREATE OR ALTER TRIGGER TBU_STOCK
    BEFORE UPDATE ON STOCK
    AS
      DECLARE C_COUNTRY CURSOR FOR (
        SELECT
          COUNTRY,
          CAPITAL
        FROM COUNTRY
      );
    BEGIN
      /* PSQL statements */
    END
                
  2. Eine Sammlung von Skripts zum Erstellen von Ansichten mit einem PSQL-Block unter Verwendung von benannten Cursors.
    EXECUTE BLOCK
    RETURNS (
        SCRIPT BLOB SUB_TYPE TEXT)
    AS
    DECLARE VARIABLE FIELDS VARCHAR(8191);
    DECLARE VARIABLE FIELD_NAME TYPE OF RDB$FIELD_NAME;
    DECLARE VARIABLE RELATION RDB$RELATION_NAME;
    DECLARE VARIABLE SOURCE   TYPE OF COLUMN RDB$RELATIONS.RDB$VIEW_SOURCE;
    DECLARE VARIABLE CUR_R      CURSOR FOR (
        SELECT
            RDB$RELATION_NAME,
            RDB$VIEW_SOURCE
        FROM
            RDB$RELATIONS
        WHERE
            RDB$VIEW_SOURCE IS NOT NULL);
    -- Declaring a named cursor where
    -- a local variable is used
    DECLARE CUR_F      CURSOR FOR (
        SELECT
            RDB$FIELD_NAME
        FROM
            RDB$RELATION_FIELDS
        WHERE
            -- It is important that the variable must be declared earlier
            RDB$RELATION_NAME = :RELATION);
    BEGIN
      OPEN CUR_R;
      WHILE (1 = 1) DO
      BEGIN
        FETCH CUR_R
        INTO :RELATION, :SOURCE;
        IF (ROW_COUNT = 0) THEN
          LEAVE;
    
        FIELDS = NULL;
        -- The CUR_F cursor will use the value
        -- of the RELATION variable initiated above
        OPEN CUR_F;
        WHILE (1 = 1) DO
        BEGIN
          FETCH CUR_F
          INTO :FIELD_NAME;
          IF (ROW_COUNT = 0) THEN
            LEAVE;
          IF (FIELDS IS NULL) THEN
            FIELDS = TRIM(FIELD_NAME);
          ELSE
            FIELDS = FIELDS || ', ' || TRIM(FIELD_NAME);
        END
        CLOSE CUR_F;
    
        SCRIPT = 'CREATE VIEW ' || RELATION;
    
        IF (FIELDS IS NOT NULL) THEN
          SCRIPT = SCRIPT || ' (' || FIELDS || ')';
    
        SCRIPT = SCRIPT || ' AS ' || ASCII_CHAR(13);
        SCRIPT = SCRIPT || SOURCE;
    
        SUSPEND;
      END
      CLOSE CUR_R;
    END
                

Siehe auch:  OPEN, FETCH, CLOSE

DECLARE VARIABLE

Inhaltsverzeichnis

Datentypen für Variablen

Verwendet für:  Deklaration einer lokalen Variablen

Verfügbar in:  PSQL

Syntax: 

DECLARE [VARIABLE] <varname>
  {<datatype> | <domain> | TYPE OF {<domain> | COLUMN <rel.col>}
    [NOT NULL]  [CHARACTER SET <charset>] [COLLATE <collation>]
    [{DEFAULT | = } <initvalue>];

<datatype> ::=
    {SMALLINT | INTEGER | BIGINT}
  | {FLOAT | DOUBLE PRECISION}
  | {DATE | TIME | TIMESTAMP}
  | {DECIMAL | NUMERIC} [(precision [, scale])]
  | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size)]
    [CHARACTER SET charset]
  | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING]
    [(size)]
  | BLOB [SUB_TYPE {subtype_num | subtype_name}]
    [SEGMENT SIZE seglen] [CHARACTER SET charset]
  | BLOB [(seglen [, subtype_num])]

<initvalue> ::= <literal> | <context_var>
        

Tabelle 7.5. DECLARE VARIABLE-Statement-Parameter

Argument Beschreibung
varname Name der lokalen Variable
datatype Ein SQL-Datentyp
domain Der Name einer bestehenden Domain in dieser Datenbank
rel.col Beziehungsname (Tabelle oder Sicht) in dieser Datenbank und der Name einer Spalte in dieser Beziehung
precision Präzision. Von 1 bis 18
scale Rahmen. Von 0 bis 18 muss es kleiner oder gleich der Genauigkeit sein
size Die maximale Größe einer Zeichenfolge in Zeichen
subtype_num BLOB-Untertyp-Nummer
subtype_name Mnemonischer Name des BLOB-Untertyp
seglen Segmentgröße, nicht größer als 65.535
initvalue Anfangswert für diese Variable
literal Literal eines Typs, der mit dem Typ der lokalen Variablen kompatibel ist
context_var Jede Kontextvariable, deren Typ mit dem Typ der lokalen Variablen kompatibel ist
charset Zeichensatz
collation Sortierfolge


Die Anweisung DECLARE [VARIABLE] wird zum Deklarieren einer lokalen Variable verwendet. Das Schlüsselwor VARIABLE kann weggelassen werden. Je ein DECLARE [VARIABLE]-Statement ist für jede Variable notwendig. Jede beliebige Anzahl von DECLARE [VARIABLE]-Statements kann in jeglicher Reihenfolge eingefügt werden. Der Name jeder lokalen Variable muss eindeutig innerhalb der lokalen Variablen und Ausgabeparametern in der Moduldeklaration sein.

Datentypen für Variablen

Eine lokale Variable kann von einem anderen SQL-Typ als ein Array sein.

  • Ein Domainname kann als Typ angegeben werden und die Variable erbt alle ihre Attribute.
  • Wenn die TYPE OF <domain>-Klausel verwendet wird, erbt die Variable nur den Datentyp der Domain und gegebenenfalls ihre Zeichensatz- und Sortierattribute. Alle Standardwerte oder Einschränkungen wie NOT NULL oder CHECK-Einschränkungen werden nicht vererbt.
  • Wenn die Option "TYPE OF COLUMN" <relation.column> verwendet wird, um Daten aus einer Spalte in einer Tabelle oder Sicht zu „leihen“, wird die Variable nur den Datentyp der Spalte erben, und gegebenenfalls ihren Zeichensatz und Sortierattribute. Alle anderen Attribute werden ignoriert.

NOT NULL-Constraint:  Die Variable kann bei Bedarf auf NOT NULL beschränkt werden. Wenn eine Domain als Datentyp angegeben wurde und bereits die NOT NULL-Einschränkung enthält, ist sie nicht erforderlich. Bei den anderen Formen, einschließlich der Verwendung einer Domain, die nullwertfähig ist, sollte das NOT NULL-Attribut bei Bedarf eingefügt werden.

CHARACTER SET- und COLLATE-Klauseln:  Sofern nicht anders angegeben, sind der Zeichensatz und die Sortierfolge einer String-Variablen die Standardeinstellungen der Datenbank. Eine Klausel CHARACTER SET kann bei Bedarf eingefügt werden, um Zeichenkettendaten zu verarbeiten, die sich in einem anderen Zeichensatz befinden. Eine gültige Sortierreihenfolge (COLLATE-Klausel) kann ebenfalls mit oder ohne die Zeichensatzklausel eingeschlossen werden.

Initialisieren einer Variablen: Lokale Variablen sind NULL, wenn die Ausführung des Moduls beginnt. Sie können initialisiert werden, sodass ein Start- oder Standardwert verfügbar ist, wenn sie zum ersten Mal referenziert werden. Die Form DEFAULT <initvalue> kann verwendet werden, oder nur der Zuweisungsoperator, "=": = <initvalue>. Der Wert kann ein beliebiges Typ-kompatibles Literal oder eine Kontextvariable sein.

Wichtig

Stellen Sie sicher, dass Sie diese Klausel für alle Variablen verwenden, die auf NOT NULL festgelegt sind und ansonsten keinen Standardwert haben.

Beispiele für verschiedene Möglichkeiten, lokale Variablen zu deklarieren: 

CREATE OR ALTER PROCEDURE SOME_PROC
AS
  -- Declaring a variable of the INT type
  DECLARE I INT;
  -- Declaring a variable of the INT type that does not allow NULL
  DECLARE VARIABLE J INT NOT NULL;
  -- Declaring a variable of the INT type with the default value of 0
  DECLARE VARIABLE K INT DEFAULT 0;
  -- Declaring a variable of the INT type with the default value of 1
  DECLARE VARIABLE L INT = 1;
  -- Declaring a variable based on the COUNTRYNAME domain
  DECLARE FARM_COUNTRY COUNTRYNAME;
  -- Declaring a variable of the type equal to the COUNTRYNAME domain
  DECLARE FROM_COUNTRY TYPE OF COUNTRYNAME;
  -- Declaring a variable with the type of the CAPITAL column in the COUNTRY table
  DECLARE CAPITAL TYPE OF COLUMN COUNTRY.CAPITAL;
BEGIN
  /* PSQL statements */
END
        

Siehe auch:  Datentypen und Unterdatentypen, Benutzerdefinierte Datentypen — Domains, CREATE DOMAIN

BEGIN ... END

Verwendet für:  Einen Block von Anweisungen abgrenzen

Verfügbar in:  PSQL

Syntax: 

<block> ::=
BEGIN
  <compound_statement>
  [<compound_statement>
  …]
END

<compound_statement> ::= {<block> | <statement>;}
        

Das Konstrukt BEGIN ... END ist eine zweiteilige Anweisung, die einen Block von Anweisungen umhüllt, die als eine Codeeinheit ausgeführt werden. Jeder Block beginnt mit der Halb-Anweisung BEGIN und endet mit der anderen Halb-Anweisung END. Blöcke können in unbegrenzter Tiefe verschachtelt werden. Sie können leer sein, so dass sie als Stubs fungieren können, ohne dass Dummy-Anweisungen geschrieben werden müssen.

Die Anweisungen BEGIN und END haben keine Zeilenabschlußzeichen. Wenn jedoch ein PSQL-Modul im Dienstprogramm isql definiert oder geändert wird, muss für diese Anwendung der letzten END-Anweisung ein eigenes Terminatorzeichen folgen, das zuvor umgeschaltet wurde. SET TERM auf eine andere Zeichenfolge als ein Semikolon. Dieser Terminator ist nicht Teil der PSQL-Syntax.

Die letzte oder äußerste END-Anweisung in einem Trigger beendet den Trigger. Was die letzte Anweisung END in einer gespeicherten Prozedur macht, hängt vom Typ der Prozedur ab:

  • In einer wählbaren Prozedur gibt die endgültige Anweisung END die Steuerung an den Aufrufer zurück und gibt SQLCODE 100 zurück, um anzugeben, dass keine weiteren Zeilen abgerufen werden müssen.
  • In einer ausführbaren Prozedur gibt die endgültige Anweisung END die Kontrolle an den Aufrufer zurück, zusammen mit den aktuellen Werten aller definierten Ausgabeparameter.

Beispiel:  Eine Beispielprozedur aus der Datenbank employee.fdb, die die einfache Verwendung der Blöcke BEGIN ... END zeigt:

SET TERM ^;
CREATE OR ALTER PROCEDURE DEPT_BUDGET (
    DNO CHAR(3))
RETURNS (
    TOT DECIMAL(12,2))
AS
    DECLARE VARIABLE SUMB DECIMAL(12,2);
    DECLARE VARIABLE RDNO CHAR(3);
    DECLARE VARIABLE CNT  INTEGER;
BEGIN
  TOT = 0;

  SELECT
      BUDGET
  FROM
      DEPARTMENT
  WHERE DEPT_NO = :DNO
  INTO :TOT;

  SELECT
      COUNT(BUDGET)
  FROM
      DEPARTMENT
  WHERE HEAD_DEPT = :DNO
  INTO :CNT;

  IF (CNT = 0) THEN
    SUSPEND;

  FOR
      SELECT
          DEPT_NO
      FROM
          DEPARTMENT
      WHERE HEAD_DEPT = :DNO
      INTO :RDNO
  DO
  BEGIN
    EXECUTE PROCEDURE DEPT_BUDGET(:RDNO)
    RETURNING_VALUES :SUMB;
    TOT = TOT + SUMB;
  END

  SUSPEND;
END^
SET TERM ;^
          

Siehe auch:  EXIT, LEAVE, SET TERM

IF ... THEN ... ELSE

Verwendet für:  Bedingte Sprünge

Verfügbar in:  PSQL

Syntax: 

IF (<condition>)
	THEN <single_statement> ; | BEGIN <compound_statement> END
[ELSE <single_statement> ; | BEGIN <compound_statement> END]
        

Tabelle 7.6. IF ... THEN ... ELSE Parameters

Argument Beschreibung
condition Eine logische Bedingung, die TRUE, FALSE oder UNKNOWN zurückgibt
single_statement Eine einzelne Anweisung wurde mit einem Semikolon abgeschlossen
compound_statement Zwei oder mehr Anweisungen, die in BEGIN ... END verpackt sind


Die bedingte Sprunganweisung IF ... THEN wird verwendet, um den Ausführungsprozess in einem PSQL-Modul zu verzweigen. Die Bedingung ist immer in Klammern eingeschlossen. Wenn es den Wert TRUE zurückgibt, verzweigt die Ausführung in die Anweisung oder den Anweisungsblock nach dem Schlüsselwort THEN. Wenn eine ELSE vorhanden ist und die Bedingung FALSE oder UNKNOWN zurückgibt, verzweigt die Ausführung in die Anweisung oder den Anweisungsblock danach.

Beispiel:  Ein Beispiel mit der IF-Anweisung. Angenommen, die Variablen FIRST, LINE2 und LAST wurden früher deklariert.

...
IF (FIRST IS NOT NULL) THEN
     LINE2 = FIRST || ' ' || LAST;
ELSE
     LINE2 = LAST;
...
          

Siehe auch:  WHILE ... DO, CASE

WHILE ... DO

Verwendet für:  Schleifenkonstrukte

Verfügbar in:  PSQL

Syntax: 

WHILE <condition> DO
<single_statement> ; | BEGIN <compound_statement> END
        

Tabelle 7.7. WHILE ... DO Parameters

Argument Beschreibung
condition Eine logische Bedingung, die TRUE, FALSE oder UNKNOWN zurückgibt
single_statement Eine einzelne Anweisung wurde mit einem Semikolon abgeschlossen
compound_statement Zwei oder mehr Anweisungen, die in BEGIN ... END verpackt sind


Eine WHILE-Anweisung implementiert das Schleifenkonstrukt in PSQL. Die Anweisung oder der Anweisungsblock wird ausgeführt, bis die Bedingung TRUE zurückgibt. Schleifen können beliebig tief verschachtelt werden.

Beispiel:  Eine Prozedur, die die Summe der Zahlen von 1 bis I berechnet, zeigt, wie das Schleifenkonstrukt verwendet wird.

CREATE PROCEDURE SUM_INT (I INTEGER)
RETURNS (S INTEGER)
AS
BEGIN
  s = 0;
  WHILE (i > 0) DO
  BEGIN
    s = s + i;
    i = i - 1;
  END
END
          

Ausführen der Prozedur in isql:

EXECUTE PROCEDURE SUM_INT(4);
          

Das Ergebnis ist:

S
==========
10
          

Siehe auch:  IF ... THEN ... ELSE, LEAVE, EXIT, FOR SELECT, FOR EXECUTE STATEMENT

LEAVE

Verwendet für:  Eine Schleife beenden

Verfügbar in:  PSQL

Syntax: 

[label:]
<loop>
BEGIN
  ...
  LEAVE [label];
  ...
END
<loop_stmt> ::=
    FOR <select_stmt> INTO <var_list> DO
  | FOR EXECUTE STATEMENT ... INTO <var_list> DO
  | WHILE (<condition>)} DO
        

Tabelle 7.8. LEAVE-Statement-Parameter

Argument Beschreibung
label Label
select_stmt SELECT-Statement
condition Eine logische Bedingung, die TRUE, FALSE oder UNKNOWN zurückgibt


Eine LEAVE-Anweisung beendet sofort die innere Schleife einer WHILE oder FOR Schleifenanweisung. Der Parameter LABEL ist optional.

LEAVE kann auch zum Beenden von äußeren Schleifen führen. Code wird weiterhin von der ersten Anweisung nach der Beendigung des äußeren Schleifenblocks ausgeführt.

Beispiele: 

  1. Eine Schleife verlassen, wenn bei einem Einfügen in die NUMBERS-Tabelle ein Fehler auftritt. Der Code wird weiterhin von der Zeile C = 0 ausgeführt.
    ...
    WHILE (B < 10) DO
    BEGIN
        INSERT INTO NUMBERS(B)
        VALUES (:B);
        B = B + 1;
        WHEN ANY DO
        BEGIN
            EXECUTE PROCEDURE LOG_ERROR (
                 CURRENT_TIMESTAMP,
                 'ERROR IN B LOOP');
            LEAVE;
        END
    END
    C = 0;
    ...
                
  2. Ein Beispiel für die Verwendung von Labels in der LEAVE-Anweisung. LEAVE LOOPA beendet die äußere Schleife und LEAVE LOOPB beendet die innere Schleife. Beachten Sie, dass die einfache Anweisung LEAVE ausreichen würde, um die innere Schleife zu beenden.
    ...
    STMT1 = 'SELECT NAME FROM FARMS';
    LOOPA:
    FOR EXECUTE STATEMENT :STMT1
    INTO :FARM DO
    BEGIN
      STMT2 = 'SELECT NAME ' || 'FROM ANIMALS WHERE FARM = ''';
      LOOPB:
      FOR EXECUTE STATEMENT :STMT2 || :FARM || ''''
      INTO :ANIMAL DO
      BEGIN
        IF (ANIMAL = 'FLUFFY') THEN
          LEAVE LOOPB;
        ELSE IF (ANIMAL = FARM) THEN
          LEAVE LOOPA;
        ELSE
          SUSPEND;
      END
    END
    ...
                

Siehe auch:  EXIT

EXIT

Verwendet für:  Beenden der Modulausführung

Verfügbar in:  PSQL

Syntax: 

EXIT;
        

Die Anweisung EXIT bewirkt, dass die Ausführung der Prozedur oder des Triggers von jedem Punkt des Codes zur endgültigen END-Anweisung springt, wodurch das Programm beendet wird.

Beispiel: Verwenden der EXIT-Anweisung in einer auswählbaren Prozedur:

CREATE PROCEDURE GEN_100
RETURNS (
  I INTEGER
)
AS
BEGIN
  I = 1;
  WHILE (1=1) DO
  BEGIN
    SUSPEND;
    IF (I=100) THEN
      EXIT;
    I = I + 1;
  END
END
          

Siehe auch:  LEAVE, SUSPEND

SUSPEND

Verwendet für:  Übergeben der Ausgabe an den Puffer und Aussetzen der Ausführung, während darauf gewartet wird, dass der Aufrufer sie abruft

Verfügbar in:  PSQL

Syntax: 

SUSPEND;
        

Die Anweisung SUSPEND wird in einer auswählbaren gespeicherten Prozedur verwendet, um die Werte von Ausgabeparametern an einen Puffer zu übergeben und die Ausführung anzuhalten. Die Ausführung bleibt ausgesetzt, bis die aufrufende Anwendung den Inhalt des Puffers abruft. Die Ausführung wird von der Anweisung direkt nach der SUSPEND-Anweisung fortgesetzt. In der Praxis ist dies wahrscheinlich eine neue Iteration eines Schleifenprozesses.

Wichtige Hinweise

  1. Anwendungen, die Schnittstellen verwenden, die die API umschließen, führen die Abrufe von auswählbaren Prozeduren transparent aus.

  2. Wenn eine SUSPEND -Anweisung in einer ausführbaren gespeicherten Prozedur ausgeführt wird, entspricht dies der Ausführung der Anweisung EXIT, was zu einer sofortigen Beendigung der Prozedur führt.

  3. SUSPENDunterbricht“ die Atomizität des Blocks, in dem es sich befindet. Wenn in einer auswählbaren Prozedur ein Fehler auftritt, werden Anweisungen, die nach der endgültigen SUSPEND-Anweisung ausgeführt werden, zurückgesetzt. Anweisungen, die vor der endgültigen SUSPEND-Anweisung ausgeführt wurden, werden erst zurückgesetzt, wenn die Transaktion zurückgesetzt wird.

Beispiel: Verwenden der Anweisung SUSPEND in einer auswählbaren Prozedur:

CREATE PROCEDURE GEN_100
RETURNS (
  I INTEGER
)
AS
BEGIN
  I = 1;
  WHILE (1=1) DO
  BEGIN
    SUSPEND;
    IF (I=100) THEN
      EXIT;
    I = I + 1;
  END
END
          

Siehe auch:  EXIT

EXECUTE STATEMENT

Verwendet für:  Ausführen dynamisch erstellter SQL-Anweisungen

Verfügbar in:  PSQL

Syntax: 

<execute_statement> ::= EXECUTE STATEMENT <argument>
  [<option> …]
  [INTO <variables>]

<argument> ::= paramless_stmt
            | (paramless_stmt)
            | (<stmt_with_params>) (<param_values>)

<param_values> ::= <named_values> | <positional_values>

<named_values> ::= paramname := value_expr
   [, paramname := value_expr ...]

<positional_values> ::= value_expr [, value_expr ...]

<option> ::= WITH {AUTONOMOUS | COMMON} TRANSACTION
           | WITH CALLER PRIVILEGES
           | AS USER user
           | PASSWORD password
           | ROLE role
           | ON EXTERNAL [DATA SOURCE] <connect_string>

<connect_string> ::= [<hostspec>] {filepath | db_alias}

<hostspec> ::= <tcpip_hostspec> | <NamedPipes_hostspec>

<tcpip_hostspec> ::= hostname:

<NamePipes_hostspec> ::= \\hostname\

<variables> ::= [:]varname [, [:]varname ...]
        

Tabelle 7.9. EXECUTE STATEMENT-Statement-Parameter

Argument Beschreibung
paramless_stmt Literale Zeichenfolge oder Variable, die eine nicht parametrisierte SQL-Abfrage enthält
stmt_with_params Literale Zeichenfolge oder Variable, die eine parametrisierte SQL-Abfrage enthält
paramname Name des SQL-Abfrageparameters
value_expr SQL-Ausdruck, der in einen Wert aufgelöst wird
user Nutzername. Dies kann eine Zeichenfolge, CURRENT_USER oder eine Zeichenfolgenvariable sein
password Passwort. Es kann eine Zeichenfolge oder eine Zeichenfolgevariable sein
role Rolle. Dies kann eine Zeichenfolge, CURRENT_ROLE oder eine Zeichenfolgenvariable sein
connection_string Verbindungszeichenfolge Es kann eine Zeichenfolge oder eine Zeichenfolgevariable sein
filepath Pfad zur primären Datenbankdatei
db_alias Datenbankalias
hostname Computername oder IP-Adresse
varname Variable


Die Anweisung EXECUTE STATEMENT verwendet einen Zeichenfolgenparameter und führt ihn wie eine DSQL-Anweisung aus. Wenn die Anweisung Daten zurückgibt, kann sie über eine INTO -Klausel an lokale Variablen übergeben werden.

Parametrisierte Anweisungen

Sie können die Parameter — entweder benannt oder positional — in der DSQL-Anweisungsfolge verwenden. Jedem Parameter muss ein Wert zugewiesen werden.

Spezielle Regeln für parametrisierte Anweisungen
  1. Benannte und positionale Parameter können nicht in einer Abfrage gemischt werden

  2. Wenn die Anweisung Parameter hat, müssen sie beim Aufruf von EXECUTE STATEMENT in Klammern stehen, unabhängig davon, ob sie direkt als Strings, als Variablennamen oder als Ausdrücke verwendet werden

  3. Jedem benannten Parameter muss in der Anweisungszeichenfolge ein Doppelpunkt (:) vorangestellt werden, jedoch nicht, wenn dem Parameter ein Wert zugewiesen ist

  4. Positionsparameter müssen ihre Werte in derselben Reihenfolge erhalten, in der sie im Abfragetext erscheinen

  5. Der Zuweisungsoperator für Parameter ist der Spezialoperator ": =", ähnlich dem Zuweisungsoperator in Pascal

  6. Jeder benannte Parameter kann mehrmals in der Anweisung verwendet werden, sein Wert muss jedoch nur einmal zugewiesen werden

  7. Bei Positionsparametern muss die Anzahl der zugewiesenen Werte genau der Anzahl der Parameterplatzhalter (Fragezeichen) in der Anweisung entsprechen

Beispiele:  Mit benannten Paramtern:

...
DECLARE license_num VARCHAR(15);
DECLARE connect_string VARCHAR (100);
DECLARE stmt VARCHAR (100) =
  'SELECT license
   FROM cars
   WHERE driver = :driver AND location = :loc';
BEGIN
  ...
  SELECT connstr
  FROM databases
  WHERE cust_id = :id
  INTO connect_string;
  ...
  FOR
    SELECT id
    FROM drivers
    INTO current_driver
  DO
  BEGIN
    FOR
      SELECT location
      FROM driver_locations
      WHERE driver_id = :current_driver
      INTO current_location
    DO
    BEGIN
      ...
      EXECUTE STATEMENT (stmt)
        (driver := current_driver,
         loc := current_location)
      ON EXTERNAL connect_string
      INTO license_num;
      ...
            

Derselbe Code mit Positionsparametern:

DECLARE license_num VARCHAR (15);
DECLARE connect_string VARCHAR (100);
DECLARE stmt VARCHAR (100) =
  'SELECT license
   FROM cars
   WHERE driver = ? AND location = ?';
BEGIN
  ...
  SELECT connstr
  FROM databases
  WHERE cust_id = :id
  into connect_string;
  ...
  FOR SELECT id
      FROM drivers
      INTO current_driver
  DO
  BEGIN
    FOR
      SELECT location
      FROM driver_locations
      WHERE driver_id = :current_driver
      INTO current_location
    DO
    BEGIN
      ...
      EXECUTE STATEMENT (stmt)
        (current_driver, current_location)
      ON EXTERNAL connect_string
      INTO license_num;
      ...
            

WITH {AUTONOMOUS | COMMON} TRANSACTION

Üblicherweise lief die ausgeführte SQL-Anweisung immer innerhalb der aktuellen Transaktion, und dies ist immer noch der Standardwert. WITH AUTONOMOUS TRANSACTION bewirkt, dass eine separate Transaktion mit denselben Parametern wie die aktuelle Transaktion gestartet wird. Es wird festgeschrieben, wenn die Anweisung ohne Fehler ausgeführt wird und andernfalls zurückgesetzt wird. WITH COMMON TRANSACTION verwendet, wenn möglich, die aktuelle Transaktion.

Wenn die Anweisung in einer separaten Verbindung ausgeführt werden muss, wird eine bereits gestartete Transaktion innerhalb dieser Verbindung verwendet, sofern verfügbar. Andernfalls wird eine neue Transaktion mit den gleichen Parametern wie die aktuelle Transaktion gestartet. Alle neuen Transaktionen, die unter dem „COMMON “-Regime gestartet wurden, werden mit der aktuellen Transaktion festgeschrieben oder zurückgesetzt.

WITH CALLER PRIVILEGES

Standardmäßig wird die SQL-Anweisung mit den Berechtigungen des aktuellen Benutzers ausgeführt. Die Angabe von WITH CALLER PRIVILEGES fügt dazu die Privilegien der aufrufenden Prozedur oder des Triggers hinzu, so als ob die Anweisung direkt von der Routine ausgeführt würde. WITH WITH CALLER PRIVILEGES hat keine Auswirkung, wenn die Klausel ON EXTERNAL ebenfalls vorhanden ist.

ON EXTERNAL [DATA SOURCE]

Mit ON EXTERNAL [DATA SOURCE] wird die SQL-Anweisung in einer separaten Verbindung zu derselben oder einer anderen Datenbank ausgeführt, möglicherweise sogar auf einem anderen Server. Wenn die Verbindungszeichenfolge NULL oder '' (leere Zeichenfolge) ist, wird die gesamte Klausel ON EXTERNAL [DATA SOURCE] als abwesend betrachtet und die Anweisung wird für die aktuelle Datenbank ausgeführt.

Verbindungspooling
  • Externe Verbindungen, die durch Anweisungen WITH COMMON TRANSACTION (der Standardwert) hergestellt werden, bleiben geöffnet, bis die aktuelle Transaktion beendet wird. Sie können durch nachfolgende Aufrufe an EXECUTE STATEMENT wiederverwendet werden, aber nur, wenn die Verbindungszeichenfolge genau gleich ist, einschließlich case
  • Externe Verbindungen, die durch Anweisungen <datenbank>WITH AUTONOMOUS TRANSACTION</datenbank> hergestellt werden, werden geschlossen, sobald die Anweisung ausgeführt wurde
  • Beachten Sie, dass Statements unter WITH AUTONOMOUS TRANSACTION-Verbindungen, die zuvor von Anweisungen unter WITH COMMON TRANSACTION geöffnet wurden, wiederverwendet werden. Wenn dies geschieht, bleibt die wiederverwendete Verbindung nach der Ausführung der Anweisung offen. (Dies geschieht, da es mindestens eine nicht-abgeschlossene Transaktion gibt!)
Transaktionspooling
  • Wenn WITH COMMON TRANSACTION aktiviert ist, werden Transaktionen so oft wie möglich wiederverwendet. Sie werden zusammen mit der aktuellen Transaktion festgeschrieben oder zurückgesetzt
  • Wenn WITH AUTONOMOUS TRANSACTION angegeben ist, wird immer eine neue Transaktion für die Anweisung gestartet. Diese Transaktion wird unmittelbar nach der Ausführung der Anweisung festgeschrieben oder zurückgesetzt
Ausnahmebehandlung

Ausnahmebehandlung: Wenn ON EXTERNAL verwendet wird, erfolgt die zusätzliche Verbindung immer über einen sogenannten externen Provider, auch wenn die Verbindung zur aktuellen Datenbank besteht. Eine der Folgen ist, dass Ausnahmen nicht auf die übliche Art und Weise abgefangen werden können. Jede von der Anweisung verursachte Ausnahme wird entweder in einen eds_connection- oder einen eds_statement-Fehler enden. Um sie in Ihrem PSQL-Code abzufangen, müssen Sie WHEN GDSCODE eds_connection, WHEN GDSCODE eds_statement oder WHEN ANY verwenden.

Anmerkung

Ohne ON EXTERNAL werden Ausnahmen auf die übliche Weise abgefangen, selbst wenn eine zusätzliche Verbindung zur aktuellen Datenbank hergestellt wird.

Verschiedene Hinweise
  • Der für die externe Verbindung verwendete Zeichensatz ist der gleiche wie für die aktuelle Verbindung
  • Zweiphasen-Commits werden nicht unterstützt

AS USER, PASSWORD und ROLE

Die optionalen Klauseln AS USER, PASSWORD und ROLE erlauben die Angabe unter welchem Benutzer und unter welcher Rolle das SQL-Statement ausgeführt wird. Die Methode der Benutzeranmeldung und die Existenz einer separaten offenen Verbindung hängt von dem Vorhandensein und den Werten der Klauseln ON EXTERNAL [DATA SOURCE], AS USER, PASSWORD und ROLE ab:

  • Wenn ON EXTERNAL verwendet wird, wird immer eine neue Verbindung aufgebaut und:
    • Wenn mindestens eines von AS USER, PASSWORD und ROLE vorhanden ist, wird die native Authentifizierung mit den angegebenen Parameterwerten versucht (lokal oder remote abhängig von der Verbindungszeichenfolge). Für fehlende Parameter werden keine Standardwerte verwendet
    • Wenn alle drei nicht vorhanden sind und die Verbindungszeichenfolge keinen Hostnamen enthält, wird die neue Verbindung auf dem lokalen Host mit demselben Benutzer und derselben Rolle wie die aktuelle Verbindung hergestellt. Der Begriff "lokal" bedeutet hier "auf der gleichen Maschine wie der Server". Dies ist nicht unbedingt der Standort des Clients
    • Wenn alle drei nicht vorhanden sind und die Verbindungszeichenfolge einen Hostnamen enthält, wird eine vertrauenswürdige Authentifizierung auf dem Remote-Host versucht (aus der Perspektive des Servers wiederum "Remote"). Wenn dies erfolgreich ist, gibt das Remote-Betriebssystem den Benutzernamen an (normalerweise das Betriebssystemkonto, unter dem der Firebird-Prozess ausgeführt wird).
  • Fehlt ON EXTERNAL:
    • Wenn mindestens eines von AS USER, PASSWORD und ROLE vorhanden ist, wird eine neue Verbindung zur aktuellen Datenbank mit den angegebenen Parameterwerten geöffnet. Für fehlende Parameter werden keine Standardwerte verwendet
    • Wenn alle drei nicht vorhanden sind, wird die Anweisung innerhalb der aktuellen Verbindung ausgeführt

Hinweis

Wenn ein Parameterwert NULL oder '' (leere Zeichenfolge) ist, wird der gesamte Parameter als abwesend betrachtet. Darüber hinaus gilt AS USER als abwesend, wenn der Wert gleich CURRENT_USER und ROLE wenn es identisch mit CURRENT_ROLE ist.

Vorsicht mit EXECUTE STATEMENT

  1. Es gibt keine Möglichkeit, die Syntax der enthaltenen Anweisung zu überprüfen
  2. Es gibt keine Abhängigkeitsprüfungen, um festzustellen, ob Tabellen oder Spalten gelöscht wurden
  3. Obwohl die Leistung in Schleifen in Firebird 2.5 erheblich verbessert wurde, ist die Ausführung immer noch erheblich langsamer als wenn dieselben Anweisungen direkt gestartet werden
  4. Rückgabewerte werden streng auf den Datentyp überprüft, um unvorhersehbare Ausnahmen für das Typcasting zu vermeiden. Beispielsweise würde die Zeichenfolge '1234' in eine Ganzzahl, 1234, konvertiert, aber 'abc' würde einen Konvertierungsfehler ergeben

Alles in allem sollte diese Funktion sehr vorsichtig verwendet werden und Sie sollten immer die Vorbehalte berücksichtigen. Wenn Sie das gleiche Ergebnis mit PSQL und / oder DSQL erzielen können, ist dies fast immer vorzuziehen.

Siehe auch:  FOR EXECUTE STATEMENT

FOR SELECT

Inhaltsverzeichnis

Der undeklarierte Cursor

Verwendet für:  Zeilenweises Durchlaufen einer ausgewählten Ergebnismenge

Verfügbar in:  PSQL

Syntax: 

FOR <select_stmt> [AS CURSOR cursorname]
DO {<single_statement> | BEGIN <compound_statement> END}
        

Tabelle 7.10. FOR SELECT-Statement-Parameter

Argument Beschreibung
select_stmt SELECT-Statement
cursorname Name des Cursors. Dieser muss eindeutig unter den Cursor-Namen im PSQL-Modul (gespeicherte Prozedur, Trigger oder PSQL-Block) sein
single_statement Eine einzelne Anweisung, die mit einem Doppelpunkt abgeschlossen wird und die gesamte Verarbeitung für diese FOR-Schleife ausführt
compound_statement Ein Anweisungsblock, der in BEGIN ... END eingeschlossen ist und der die gesamte Verarbeitung für diese FOR-Schleife ausführt


Ein FOR SELECT-Statement

  • ruft jede Zeile sequenziell aus der Ergebnismenge ab und führt die Anweisung oder den Anweisungsblock in der Zeile aus. In jeder Iteration der Schleife werden die Feldwerte der aktuellen Zeile in vordefinierte Variablen kopiert.

    Mit der Klausel AS CURSOR können positionierte Löschungen und Aktualisierungen durchgeführt werden, siehe unten

  • kann andere FOR SELECT-Anweisungen einbetten
  • kann benannte Parameter enthalten, die zuvor in der DECLARE VARIABLE-Anweisung deklariert werden müssen, oder als Eingabe- oder Ausgabeparameter der Prozedur vorhanden sein
  • erfordert eine INTO-Klausel, die sich am Ende der SELECT ... FROM ...-Spezifikation befindet. In jeder Iteration der Schleife werden die Feldwerte in der aktuellen Zeile in die Liste der Variablen kopiert, die in der Klausel INTO angegeben sind. Die Schleife wird wiederholt, bis alle Zeilen abgerufen wurden. Danach wird sie beendet
  • kann mit einem LEAVE-Statement beendet werden, bevor alle Zeilen abgeholt wurden.

Der undeklarierte Cursor

Die optionale AS CURSOR-Klausel behandelt den Satz in der FOR SELECT-Struktur als nicht deklarierten benannten Cursor, der mit der WHERE CURRENT OF-Klausel bearbeitet werden kann, innerhalb der Anweisung oder des Blocks nach dem Befehl DO, um die aktuelle Zeile zu löschen oder zu aktualisieren, bevor die Ausführung zur nächsten Iteration übergeht.

Weitere Punkte, die in Bezug auf nicht deklarierte Cursor berücksichtigt werden müssen:

  1. Die Anweisungen OPEN, FETCH und CLOSE können nicht auf einen Cursor angewendet werden, der durch die Klausel AS CURSOR angezeigt wird
  2. Das Argument cursorname, das einer Klausel AS CURSOR zugeordnet ist, darf nicht mit Namen kollidieren, die von den Anweisungen DECLARE VARIABLE oder DECLARE CURSOR am Anfang der body-Codes, noch mit anderen Cursorn, die durch eine Klausel AS CURSOR erstellt wurden
  3. Die optionale Klausel FOR UPDATE in der Anweisung SELECT ist für ein positioniertes Update nicht erforderlich

Beispiele für die Verwendung von FOR SELECT: 

  1. Eine einfache Schleife durch Abfrageergebnisse:
    CREATE PROCEDURE SHOWNUMS
    RETURNS (
      AA INTEGER,
      BB INTEGER,
      SM INTEGER,
      DF INTEGER)
    AS
    BEGIN
      FOR SELECT DISTINCT A, B
          FROM NUMBERS
        ORDER BY A, B
        INTO AA, BB
      DO
      BEGIN
        SM = AA + BB;
        DF = AA - BB;
        SUSPEND;
      END
    END
                
  2. Geschachtelte FOR SELECT-Schleife:
    CREATE PROCEDURE RELFIELDS
    RETURNS (
      RELATION CHAR(32),
      POS INTEGER,
      FIELD CHAR(32))
    AS
    BEGIN
      FOR SELECT RDB$RELATION_NAME
          FROM RDB$RELATIONS
          ORDER BY 1
          INTO :RELATION
      DO
      BEGIN
        FOR SELECT
              RDB$FIELD_POSITION + 1,
              RDB$FIELD_NAME
            FROM RDB$RELATION_FIELDS
            WHERE
              RDB$RELATION_NAME = :RELATION
            ORDER BY RDB$FIELD_POSITION
            INTO :POS, :FIELD
        DO
        BEGIN
          IF (POS = 2) THEN
            RELATION = ' "';
    
          SUSPEND;
        END
      END
    END
                
  3. Verwenden Sie die AS CURSOR-Klausel, um einen Cursor für das positionierte Löschen eines Datensatzes zu verwenden:
    CREATE PROCEDURE DELTOWN (
      TOWNTODELETE VARCHAR(24))
    RETURNS (
      TOWN VARCHAR(24),
      POP INTEGER)
    AS
    BEGIN
      FOR SELECT TOWN, POP
          FROM TOWNS
          INTO :TOWN, :POP AS CURSOR TCUR
      DO
      BEGIN
        IF (:TOWN = :TOWNTODELETE) THEN
          -- Positional delete
          DELETE FROM TOWNS
          WHERE CURRENT OF TCUR;
        ELSE
          SUSPEND;
      END
    END
                

Siehe auch:  DECLARE CURSOR, LEAVE, SELECT, UPDATE, DELETE

FOR EXECUTE STATEMENT

Verwendet für:  Ausführen von dynamisch erstellten SQL-Anweisungen, die einen Zeilensatz zurückgeben

Verfügbar in:  PSQL

Syntax: 

FOR <execute_statement> DO {<single_statement> | BEGIN <compound_statement> END}
        

Tabelle 7.11. FOR EXECUTE STATEMENT-Statement-Parameter

Argument Beschreibung
execute_stmt Ein EXECUTE STATEMENT-String
single_statement Eine einzelne Anweisung, die mit einem Doppelpunkt abgeschlossen wird und die gesamte Verarbeitung für diese FOR-Schleife ausführt
compound_statement Ein Anweisungsblock, der in BEGIN ... END eingeschlossen ist und der die gesamte Verarbeitung für diese FOR-Schleife ausführt


Die Anweisung FOR EXECUTE STATEMENT wird in Analogie zu FOR SELECT verwendet, um die Ergebnismenge einer dynamisch ausgeführten Abfrage, die mehrere Zeilen zurückgibt, zu durchlaufen.

Beispiel:  Ausführen einer dynamisch erstellten Abfrage SELECT, die einen Datensatz zurückgibt:

CREATE PROCEDURE DynamicSampleThree (
   Q_FIELD_NAME VARCHAR(100),
   Q_TABLE_NAME VARCHAR(100)
) RETURNS(
  LINE VARCHAR(32000)
)
AS
  DECLARE VARIABLE P_ONE_LINE VARCHAR(100);
BEGIN
  LINE = '';
  FOR
    EXECUTE STATEMENT
      'SELECT T1.' || :Q_FIELD_NAME ||
      ' FROM ' || :Q_TABLE_NAME || ' T1 '
    INTO :P_ONE_LINE
  DO
    IF (:P_ONE_LINE IS NOT NULL) THEN
      LINE = :LINE || :P_ONE_LINE || ' ';
  SUSPEND;
END
          

Siehe auch:  EXECUTE STATEMENT

OPEN

Verwendet für:  Öffnen eines deklarierten Cursors

Verfügbar in:  PSQL

Syntax: 

OPEN cursorname;
        

Tabelle 7.12. OPEN Statement Parameter

Argument Beschreibung
cursorname Name des Cursors. Ein Cursor mit diesem Namen muss zuvor mit einer DECLARE CURSOR-Anweisung deklariert werden


Eine OPEN -Anweisung öffnet einen zuvor deklarierten Cursor, führt die für sie deklarierte SELECT -Anweisung aus und macht den ersten Datensatz zum abzurufenden Ergebnisdatensatz. OPEN kann nur auf zuvor in einer DECLARE VARIABLE-Anweisung deklarierte Cursor angewendet werden.

Anmerkung

Wenn die für den Cursor deklarierte Anweisung SELECT über Parameter verfügt, müssen sie als lokale Variablen deklariert sein oder als Ein- oder Ausgabeparameter vor dem Deklarieren des Cursors vorhanden sein. Wenn der Cursor geöffnet wird, wird dem Parameter der aktuelle Wert der Variablen zugewiesen.

Beispiele: 

  1. Verwenden der OPEN-Anweisung:
    SET TERM ^;
    
    CREATE OR ALTER PROCEDURE GET_RELATIONS_NAMES
    RETURNS (
      RNAME CHAR(31)
    )
    AS
      DECLARE C CURSOR FOR (
        SELECT RDB$RELATION_NAME
        FROM RDB$RELATIONS);
    BEGIN
      OPEN C;
      WHILE (1 = 1) DO
      BEGIN
        FETCH C INTO :RNAME;
        IF (ROW_COUNT = 0) THEN
          LEAVE;
        SUSPEND;
      END
      CLOSE C;
    END^
    
    SET TERM ;^
                
  2. Eine Sammlung von Skripts zum Erstellen von Ansichten mit einem PSQL-Block mit benannten Cursorn:
    EXECUTE BLOCK
    RETURNS (
        SCRIPT BLOB SUB_TYPE TEXT)
    AS
    DECLARE VARIABLE FIELDS VARCHAR(8191);
    DECLARE VARIABLE FIELD_NAME TYPE OF RDB$FIELD_NAME;
    DECLARE VARIABLE RELATION RDB$RELATION_NAME;
    DECLARE VARIABLE SOURCE   TYPE OF COLUMN RDB$RELATIONS.RDB$VIEW_SOURCE;
    -- named cursor
    DECLARE VARIABLE CUR_R      CURSOR FOR (
        SELECT
            RDB$RELATION_NAME,
            RDB$VIEW_SOURCE
        FROM
            RDB$RELATIONS
        WHERE
            RDB$VIEW_SOURCE IS NOT NULL);
    -- named cursor with local variable
    DECLARE CUR_F      CURSOR FOR (
        SELECT
            RDB$FIELD_NAME
        FROM
            RDB$RELATION_FIELDS
        WHERE
              -- Important! The variable shall be declared earlier
            RDB$RELATION_NAME = :RELATION);
    BEGIN
      OPEN CUR_R;
      WHILE (1 = 1) DO
      BEGIN
        FETCH CUR_R
        INTO :RELATION, :SOURCE;
        IF (ROW_COUNT = 0) THEN
          LEAVE;
    
        FIELDS = NULL;
            -- The CUR_F cursor will use
            -- variable value of RELATION initialized above
        OPEN CUR_F;
        WHILE (1 = 1) DO
        BEGIN
          FETCH CUR_F
          INTO :FIELD_NAME;
          IF (ROW_COUNT = 0) THEN
            LEAVE;
          IF (FIELDS IS NULL) THEN
            FIELDS = TRIM(FIELD_NAME);
          ELSE
            FIELDS = FIELDS || ', ' || TRIM(FIELD_NAME);
        END
        CLOSE CUR_F;
    
        SCRIPT = 'CREATE VIEW ' || RELATION;
    
        IF (FIELDS IS NOT NULL) THEN
          SCRIPT = SCRIPT || ' (' || FIELDS || ')';
    
        SCRIPT = SCRIPT || ' AS ' || ASCII_CHAR(13);
        SCRIPT = SCRIPT || SOURCE;
    
        SUSPEND;
      END
      CLOSE CUR_R;
    END
                

Siehe auch:  DECLARE CURSOR, FETCH, CLOSE

FETCH

Verwendet für:  Abrufen aufeinanderfolgender Datensätze aus einem Datensatz, der mit einem Cursor abgerufen wurde

Verfügbar in:  PSQL

Syntax: 

FETCH cursorname INTO [:]varname [, [:]varname ...];
        

Tabelle 7.13. FETCH-Statement-Parameter

Argument Beschreibung
cursorname Name des Cursors Ein Cursor mit diesem Namen muss zuvor mit einer DECLARE CURSOR-Anweisung deklariert und durch eine OPEN-Anweisung geöffnet werden.
varname Variablenname


Eine FETCH-Anweisung ruft die erste und die folgenden Zeilen aus der Ergebnismenge des Cursors ab und weist PSQL-Variablen die Spaltenwerte zu. Die Anweisung FETCH kann nur mit einem Cursor verwendet werden, der mit der Anweisung DECLARE CURSOR deklariert wurde.

Die INTO-Klausel ruft Daten aus der aktuellen Zeile des Cursors ab und lädt sie in PSQL-Variablen.

Um zu überprüfen, ob alle Datensatzzeilen abgerufen wurden, gibt die Kontextvariable ROW_COUNT die Anzahl der Zeilen zurück, die von der Anweisung abgerufen wurden. Es ist positiv, bis alle Zeilen überprüft wurden. Ein ROW_COUNT von 1 gibt an, dass der nächste Abruf der letzte sein wird.

Beispiel:  Verwenden der FETCH-Anweisung:

SET TERM ^;

CREATE OR ALTER PROCEDURE GET_RELATIONS_NAMES
RETURNS (
  RNAME CHAR(31)
)
AS
  DECLARE C CURSOR FOR (
    SELECT RDB$RELATION_NAME
    FROM RDB$RELATIONS);
BEGIN
  OPEN C;
  WHILE (1 = 1) DO
  BEGIN
    FETCH C INTO :RNAME;
    IF (ROW_COUNT = 0) THEN
      LEAVE;
    SUSPEND;
  END
  CLOSE C;
END^

SET TERM ;^
          

Siehe auch:  DECLARE CURSOR, OPEN, CLOSE

CLOSE

Verwendet für:  Einen deklarierten Cursor schließen

Verfügbar in:  PSQL

Syntax: 

CLOSE cursorname;
        

Tabelle 7.14. CLOSE-Statement-Parameter

Argument Beschreibung
cursorname Name des Cursors. Ein Cursor mit diesem Namen muss zuvor mit einer DECLARE CURSOR-Anweisung deklariert und durch eine OPEN-Anweisung geöffnet werden


Eine Anweisung CLOSE schließt einen geöffneten Cursor. Alle Cursor, die noch geöffnet sind, werden automatisch geschlossen, nachdem der Modulcode ausgeführt wurde. Nur ein Cursor, der mit DECLARE CURSOR deklariert wurde, kann mit einer CLOSE-Anweisung geschlossen werden.

Beispiel:  Verwenden der CLOSE-Anweisung:

SET TERM ^;

CREATE OR ALTER PROCEDURE GET_RELATIONS_NAMES
RETURNS (
  RNAME CHAR(31)
)
AS
  DECLARE C CURSOR FOR (
    SELECT RDB$RELATION_NAME
    FROM RDB$RELATIONS);
BEGIN
  OPEN C;
  WHILE (1 = 1) DO
  BEGIN
    FETCH C INTO :RNAME;
    IF (ROW_COUNT = 0) THEN
      LEAVE;
    SUSPEND;
  END
  CLOSE C;
END^
          

Siehe auch:  DECLARE CURSOR, OPEN, FETCH

IN AUTONOMOUS TRANSACTION

Verwendet für:  Eine Anweisung oder einen Block von Anweisungen in einer autonomen Transaktion ausführen

Verfügbar in:  PSQL

Syntax: 

IN AUTONOMOUS TRANSACTION DO <compound_statement>
        

Tabelle 7.15. IN AUTONOMOUS TRANSACTION Statement Parameter

Argument Beschreibung
compound_statement Ein Statement oder ein Block von Statements


Eine Anweisung IN AUTONOMOUS TRANSACTION ermöglicht die Ausführung einer Anweisung oder eines Anweisungsblocks in einer autonomen Transaktion. Code, der in einer autonomen Transaktion ausgeführt wird, wird unmittelbar nach seiner erfolgreichen Ausführung unabhängig vom Status seiner übergeordneten Transaktion festgeschrieben. Dies kann erforderlich sein, wenn bestimmte Vorgänge nicht zurückgesetzt werden sollen, auch wenn in der übergeordneten Transaktion ein Fehler auftritt.

Eine autonome Transaktion hat dieselbe Isolationsstufe wie ihre übergeordnete Transaktion. Jede Ausnahme, die im Block des autonomen Transaktionscodes ausgelöst wird, führt dazu, dass die autonome Transaktion zurückgesetzt wird und alle vorgenommenen Änderungen storniert werden. Wenn der Code erfolgreich ausgeführt wird, wird die autonome Transaktion festgeschrieben.

Beispiel:  Verwenden einer autonomen Transaktion in einem Trigger für das Datenbankereignis ON CONNECT, um alle Verbindungsversuche einschließlich der fehlgeschlagenen zu protokollieren:

CREATE TRIGGER TR_CONNECT ON CONNECT
AS
BEGIN
  -- Logging all attempts to connect to the database
  IN AUTONOMOUS TRANSACTION DO
    INSERT INTO LOG(MSG)
    VALUES ('USER ' || CURRENT_USER || ' CONNECTS.');
  IF (CURRENT_USER IN (SELECT
                           USERNAME
                       FROM
                           BLOCKED_USERS)) THEN
  BEGIN
    -- Logging that the attempt to connect
    -- to the database failed and sending
    -- a message about the event
    IN AUTONOMOUS TRANSACTION DO
    BEGIN
      INSERT INTO LOG(MSG)
      VALUES ('USER ' || CURRENT_USER || ' REFUSED.');
      POST_EVENT 'CONNECTION ATTEMPT' || ' BY BLOCKED USER!';
    END
    -- now calling an exception
    EXCEPTION EX_BADUSER;
  END
END
          

Siehe auch:  Transaktionskontrolle

POST_EVENT

Verwendet für:  Benachrichtigung von Listening-Clients über Datenbankereignisse in einem Modul

Verfügbar in:  PSQL

Syntax: 

POST_EVENT event_name;
        

Tabelle 7.16. POST_EVENT Statement Parameter

Argument Beschreibung
event_name Ereignisname (Nachricht) ist auf 127 Byte beschränkt


Die Anweisung POST_EVENT benachrichtigt den Ereignismanager über das Ereignis, das es in einer Ereignistabelle speichert. Wenn die Transaktion festgeschrieben wird, benachrichtigt der Ereignismanager Anwendungen, die ihr Interesse an dem Ereignis signalisieren.

Der Ereignisname kann eine Art Code oder eine kurze Nachricht sein: Die Auswahl ist offen, da sie nur eine Zeichenfolge von bis zu 127 Bytes ist.

Der Inhalt der Zeichenfolge kann ein Zeichenfolgenliteral, eine Variable oder ein beliebiger gültiger SQL-Ausdruck sein, der in eine Zeichenfolge aufgelöst wird.

Beispiel:  Benachrichtigung der zuhörenden Anwendungen über das Einfügen eines Datensatzes in die SALES-Tabelle:

SET TERM ^;
CREATE TRIGGER POST_NEW_ORDER FOR SALES
ACTIVE AFTER INSERT POSITION 0
AS
BEGIN
  POST_EVENT 'new_order';
END^
SET TERM ;^
          

Zurück: TriggerFirebird Documentation IndexNach oben: Prozedurale SQL-Anweisungen (PSQL)Weiter: Abfangen und Behandeln von Fehlern
Firebird Documentation IndexFirebird 2.5 SprachreferenzProzedurale SQL-Anweisungen (PSQL) → Schreiben des Body-Codes