FirebirdSQL logo

DECLARE PROCEDURE

Verwendet für

Deklaration eines Unterverfahrens

Verfügbar in

PSQL

Syntax
<declare-subproc> ::= <subproc-forward> | <subproc-def>

<subproc-forward> ::= <subproc-header>;

<subproc-def> ::= <subproc-header> <psql-module-body>

<subproc-header>  ::=
DECLARE subprocname [ ( [ <in_params> ] ) ]
  [RETURNS (<out_params>)]

<in_params> ::=
  !! Siehe auch CREATE PROCEDURE-Syntax !!

<domain_or_non_array_type> ::=
  !! Siehe auch Syntax für skalare Datentypen !!

<psql-module-body> ::=
  !! Siehe auch Syntax des Modul-Bodys !!
Table 1. DECLARE PROCEDURE-Anweisungsparameter
Argument Beschreibung

subprocname

Name des Unterverfahrens

collation

Kollationsname

Die Anweisung DECLARE PROCEDURE deklariert eine Unterprozedur.Eine Unterprozedur ist nur für das PSQL-Modul sichtbar, das die Unterprozedur definiert hat.

Unterverfahren haben eine Reihe von Einschränkungen:

  • Eine Unterprozedur kann nicht in eine andere Unterroutine geschachtelt werden.Unterroutinen werden nur in PSQL-Modulen der obersten Ebene unterstützt (gespeicherte Prozeduren, gespeicherte Funktionen, Trigger und anonyme PSQL-Blöcke).Diese Einschränkung wird durch die Syntax nicht erzwungen, aber Versuche, verschachtelte Unterprozeduren zu erstellen, führen zu einem Fehler “feature is not supported” mit der Detailmeldung “nested sub procedure”.

  • Derzeit hat die Unterprozedur keinen direkten Zugriff, um Variablen und Cursor aus ihrem Elternmodul zu verwenden.Es kann von seinen Elternmodulen auf andere Routinen zugreifen.In einigen Fällen kann eine Voranmeldung erforderlich sein.

Eine Unterprozedur kann vorwärts deklariert werden, um gegenseitige Abhängigkeiten zwischen Unterroutinen aufzulösen, und muss von ihrer tatsächlichen Definition gefolgt werden.Wenn eine Unterprozedur vorwärts deklariert ist und Parameter mit Standardwerten hat, sollten die Standardwerte nur in der Vorwärtsdeklaration angegeben und nicht in subproc_def wiederholt werden.

Note

Wenn Sie eine Unterprozedur mit demselben Namen wie eine gespeicherte Prozedur, Tabelle oder Ansicht deklarieren, wird diese gespeicherte Prozedur, Tabelle oder Ansicht von Ihrem Modul ausgeblendet.Es ist nicht möglich, diese gespeicherte Prozedur, Tabelle oder Ansicht aufzurufen.

Note

Im Gegensatz zu DECLARE [VARIABLE] wird ein DECLARE PROCEDURE nicht mit einem Semikolon abgeschlossen.Das END seines Hauptblocks BEGIN …​ END wird als sein Abschlusszeichen betrachtet.

Beispiele für Unterprozeduren

Unterprogramme in EXECUTE BLOCK

+

EXECUTE BLOCK
  RETURNS (name VARCHAR(63))
AS
-- Unterprozedur, die eine Liste von Tabellen zurückgibt
  DECLARE PROCEDURE get_tables
    RETURNS (table_name VARCHAR(63))
  AS
  BEGIN
    FOR SELECT RDB$RELATION_NAME
      FROM RDB$RELATIONS
      WHERE RDB$VIEW_BLR IS NULL
      INTO table_name
    DO SUSPEND;
  END
-- Unterprozedur, die eine Liste von Ansichten zurückgibt
  DECLARE PROCEDURE get_views
    RETURNS (view_name VARCHAR(63))
  AS
  BEGIN
    FOR SELECT RDB$RELATION_NAME
      FROM RDB$RELATIONS
      WHERE RDB$VIEW_BLR IS NOT NULL
      INTO view_name
    DO SUSPEND;
  END
BEGIN
  FOR SELECT table_name
    FROM get_tables
    UNION ALL
    SELECT view_name
    FROM get_views
    INTO name
  DO SUSPEND;
END
  1. Mit Vorwärtsdeklaration und Parameter mit Standardwert

    execute block returns (o integer)
    as
        -- Vorwärtsdeklaration von P1.
        declare procedure p1(i integer = 1) returns (o integer);
    
        -- Vorwärtsdeklaration von P2.
        declare procedure p2(i integer) returns (o integer);
    
        -- Die Implementierung von P1 sollte den Parameterstandardwert nicht neu deklarieren.
        declare procedure p1(i integer) returns (o integer)
        as
        begin
            execute procedure p2(i) returning_values o;
        end
    
        declare procedure p2(i integer) returns (o integer)
        as
        begin
            o = i;
        end
    begin
        execute procedure p1 returning_values o;
        suspend;
    end

BEGIN …​ END

Verwendet für

Einen Block von Anweisungen abgrenzen

Verfügbar in

PSQL

Syntax
<block> ::=
  BEGIN
    [<compound_statement> ...]
  END

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

Das Konstrukt BEGIN …​ END ist eine zweiteilige Anweisung, die einen Block von Anweisungen umschließt, die als eine Codeeinheit ausgeführt werden.Jeder Block beginnt mit der Halbanweisung "BEGIN" und endet mit der anderen Halbanweisung "END".Blöcke können mit einer maximalen Tiefe von 512 verschachtelten Blöcken verschachtelt werden.Ein Block kann leer sein, sodass sie als Stubs fungieren können, ohne dass Dummy-Anweisungen geschrieben werden müssen.

Die Anweisungen BEGIN und END haben keine Zeilenabschlusszeichen (Semikolon).Beim Definieren oder Ändern eines PSQL-Moduls im Dienstprogramm isql erfordert diese Anwendung jedoch, dass der letzten END-Anweisung ein eigenes Abschlusszeichen folgt, das zuvor mit SET TERM in eine andere Zeichenfolge als umgestellt wurde 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 END-Anweisung in einer Stored Procedure macht, hängt vom Prozedurtyp ab:

  • In einer auswählbaren Prozedur gibt die letzte END-Anweisung die Kontrolle an den Aufrufer zurück und gibt SQLCODE 100 zurück, was angibt, dass keine weiteren Zeilen zum Abrufen vorhanden sind

  • In einer ausführbaren Prozedur gibt die letzte END-Anweisung die Kontrolle an den Aufrufer zurück, zusammen mit den aktuellen Werten aller definierten Ausgabeparameter.

BEGIN …​ END-Beispiele

Eine Beispielprozedur aus der Datenbank employee.fdb, die die einfache Verwendung von BEGIN…​END-Blöcken 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 ;^