FirebirdSQL logo

CREATE FUNCTION

Verwendet für

Erstellen einer neuen gespeicherten Funktion

Verfügbar in

DSQL

Syntax
CREATE FUNCTION funcname [ ( [ <in_params> ] ) ]
  RETURNS <domain_or_non_array_type> [COLLATE collation]
  [DETERMINISTIC]
  {<psql_function> | <external-module-body>}

<in_params> ::= <inparam> [, <inparam> ... ]

<inparam> ::= <param-decl> [ { = | DEFAULT } <value> ]

<value> ::= { <literal> | NULL | <context-var> }

<param-decl> ::= paramname <domain_or_non_array_type> [NOT NULL]
  [COLLATE collation]

<domain_or_non_array_type> ::=
  !! Vgl. Skalardatentyp-Syntax !!

<psql_function> ::=
  [SQL SECURITY {INVOKER | DEFINER}]
  <psql-module-body>

<psql-module-body> ::=
  !! Vgl. Syntax des Modulrumpfes !!

<external-module-body> ::=
  !! Vgl. Syntax des Modulrumpfes !!
Table 1. CREATE FUNCTION-Anweisungsparameter
Parameter Beschreibung

funcname

Name der gespeicherten Funktion.Maximal 63 Zeichen.Muss unter allen Funktionsnamen in der Datenbank eindeutig sein.

inparam

Beschreibung der Eingabeparameter

collation

Sortierreihenfolge

literal

Ein Literalwert, der mit dem Datentyp des Parameters zuweisungskompatibel ist

context-var

Jede Kontextvariable, deren Typ mit dem Datentyp des Parameters kompatibel ist

paramname

Der Name eines Eingabeparameters der Funktion.Er kann aus bis zu 63 Zeichen bestehen.Der Name des Parameters muss unter den Eingabeparametern der Funktion und ihren lokalen Variablen eindeutig sein.

Die Anweisung CREATE FUNCTION erstellt eine neue gespeicherte Funktion.Der gespeicherte Funktionsname muss unter den Namen aller gespeicherten und externen (alten) Funktionen eindeutig sein, mit Ausnahme von Unterfunktionen oder Funktionen in Paketen.Bei Unterfunktionen oder Funktionen in Paketen muss der Name innerhalb ihres Moduls (Paket, Stored Procedure, Stored Function, Trigger) eindeutig sein.

Note

Es ist ratsam, Funktionsnamen zwischen globalen gespeicherten Funktionen und gespeicherten Funktionen in Paketen nicht wiederzuverwenden, obwohl dies zulässig ist.Momentan ist es nicht möglich, eine Funktion oder Prozedur aus dem globalen Namensraum innerhalb eines Pakets aufzurufen, wenn dieses Paket eine Funktion oder Prozedur mit demselben Namen definiert.In dieser Situation wird die Funktion oder Prozedur des Pakets aufgerufen.

CREATE FUNCTION ist eine zusammengesetzte Anweisung mit einem Header und einem Body.Der Header definiert den Namen der gespeicherten Funktion und deklariert Eingabeparameter und Rückgabetyp.

Der Funktionsrumpf besteht aus optionalen Deklarationen von lokalen Variablen, benannten Cursorn und Unterprogrammen (Unterfunktionen und Unterprozeduren) und einer oder mehreren Anweisungen oder Anweisungsblöcken, eingeschlossen in einen äußeren Block, der mit dem Schlüsselwort BEGIN beginnt und endet mit dem Schlüsselwort END.Deklarationen und Anweisungen innerhalb des Funktionsrumpfs müssen mit einem Semikolon (‘;’) abgeschlossen werden.

Statement-Terminatoren

Einige SQL-Anweisungseditoren – insbesondere das mit Firebird gelieferte 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 beim Codieren in diesen Umgebungen zu einem Konflikt mit der PSQL-Syntax.Wenn Sie dieses Problem und seine Lösung nicht kennen, lesen Sie bitte die Details im PSQL-Kapitel im Abschnitt Terminator in isql umschalten.

docnext count = 18

Parameter

Jeder Parameter hat einen Datentyp.

Eine Kollatierungssequenz kann für String-Typ-Parameter mit der COLLATE-Klausel angegeben werden.

Eingabeparameter

Eingabeparameter werden als Liste in Klammern nach dem Namen der Funktion angezeigt.Sie werden als Wert an die Funktion übergeben, sodass Änderungen innerhalb der Funktion keine Auswirkungen auf die Parameter im Aufrufer haben.Die NOT NULL-Einschränkung kann auch für jeden Eingabeparameter angegeben werden, um zu verhindern, dass NULL übergeben oder zugewiesen wird.Eingabeparameter können Standardwerte haben.Parameter mit angegebenen Standardwerten müssen am Ende der Parameterliste hinzugefügt werden.

Ausgabeparameter

Die RETURNS-Klausel gibt den Rückgabetyp der gespeicherten Funktion an.Wenn eine Funktion einen String-Wert zurückgibt, ist es möglich, die Sortierung mit der COLLATE-Klausel anzugeben.Als Rückgabetyp können Sie einen Datentyp, einen Domänennamen, den Typ einer Domäne (mit TYPE OF) oder den Typ einer Spalte einer Tabelle oder View (mit TYPE OF COLUMN) angeben.

Deterministische Funktionen

Die optionale DETERMINISTIC-Klausel gibt an, dass die Funktion deterministisch ist.Deterministische Funktionen geben immer das gleiche Ergebnis für den gleichen Satz von Eingaben zurück.Nicht-deterministische Funktionen können für jeden Aufruf unterschiedliche Ergebnisse zurückgeben, sogar für denselben Satz von Eingaben.Wenn eine Funktion als deterministisch angegeben ist, wird eine solche Funktion möglicherweise nicht erneut aufgerufen, wenn sie bereits einmal mit den angegebenen Eingaben aufgerufen wurde, sondern übernimmt das Ergebnis aus einem Metadaten-Cache.

Note

Aktuelle Versionen von Firebird speichern Ergebnisse deterministischer Funktionen nicht wirklich.

Die Angabe der DETERMINISTIC-Klausel ist eigentlich so etwas wie ein “Versprechen”, dass die Funktion für gleiche Eingaben dasselbe zurückgibt.Im Moment wird eine deterministische Funktion als Invariante betrachtet und funktioniert wie andere Invarianten.Das heißt, sie werden auf der aktuellen Ausführungsebene einer bestimmten Anweisung berechnet und zwischengespeichert.

Dies lässt sich leicht an einem Beispiel demonstrieren:

CREATE FUNCTION FN_T
RETURNS DOUBLE PRECISION DETERMINISTIC
AS
BEGIN
  RETURN rand();
END;

-- die Funktion wird zweimal ausgewertet und gibt 2 verschiedene Werte zurück
SELECT fn_t() FROM rdb$database
UNION ALL
SELECT fn_t() FROM rdb$database;

-- die Funktion wird einmal ausgewertet und gibt 2 identische Werte zurück
WITH t (n) AS (
  SELECT 1 FROM rdb$database
  UNION ALL
  SELECT 2 FROM rdb$database
)
SELECT n, fn_t() FROM t;

SQL-Sicherheit

Die SQL SECURITY-Klausel gibt den Sicherheitskontext zum Ausführen anderer Routinen oder zum Einfügen in andere Tabellen an.Wenn SQL-Sicherheit nicht angegeben ist, wird der Standardwert der Datenbank zur Laufzeit angewendet.

Die Klausel SQL SECURITY kann nur für PSQL-Funktionen angegeben werden und gilt nicht für in einem Paket definierte Funktionen.

Siehe auch SQL-Sicherheit im Kapitel Sicherheit.

Variablen-, Cursor- und Sub-Routine-Deklarationen

Der optionale Deklarationsabschnitt, der sich am Anfang des Hauptteils der Funktionsdefinition befindet, definiert Variablen (einschließlich Cursors) und funktionslokale Unterroutinen.Lokale Variablendeklarationen folgen den gleichen Regeln wie Parameter bezüglich der Angabe des Datentyps.Weitere Informationen finden Sie im PSQL-Kapitel für DECLARE VARIABLE, DECLARE CURSOR, DECLARE FUNCTION und DECLARE PROCEDURE.

Funktionsrumpf

Auf den Header-Abschnitt folgt der Funktionsrumpf, der aus einer oder mehreren PSQL-Anweisungen besteht, die zwischen den äußeren Schlüsselwörtern BEGIN und END eingeschlossen sind.Mehrere BEGIN …​ END-Blöcke von beendeten Anweisungen können in den Prozedurrumpf eingebettet werden.

Externe UDR-Funktionen

Eine gespeicherte Funktion kann sich auch in einem externen Modul befinden.In diesem Fall spezifiziert CREATE FUNCTION anstelle eines Funktionsrumpfs die Position der Funktion im externen Modul mit der EXTERNAL-Klausel.Die optionale NAME-Klausel spezifiziert den Namen des externen Moduls, den Namen der Funktion innerhalb des Moduls und – optional – benutzerdefinierte Informationen.Die erforderliche ENGINE-Klausel gibt den Namen der UDR-Engine an, die die Kommunikation zwischen Firebird und dem externen Modul handhabt.Die optionale AS-Klausel akzeptiert ein String-Literal “body”, das von der Engine oder dem Modul für verschiedene Zwecke verwendet werden kann.

Warning

Externe UDR (User Defined Routine)-Funktionen, die mit CREATE FUNCTION …​ EXTERNAL …​ erstellt wurden, sollten nicht mit älteren UDFs (User Defined Functions) verwechselt werden, die mit DECLARE EXTERNAL FUNCTION deklariert wurden.

UDFs sind veraltet und ein Erbe früherer Firebird-Funktionen.Ihre Fähigkeiten sind den Fähigkeiten der neuen Art von externen UDR-Funktionen deutlich unterlegen.

Wer kann eine Funktion erstellen?

Die CREATE FUNCTION-Anweisung kann ausgeführt werden durch:

Der Benutzer, der die gespeicherte Funktion erstellt hat, wird deren Eigentümer.

CREATE FUNCTION-Beispiele

  1. Erstellen einer gespeicherten Funktion

    CREATE FUNCTION ADD_INT (A INT, B INT DEFAULT 0)
    RETURNS INT
    AS
    BEGIN
      RETURN A + B;
    END

    Aufruf einer Auswahl:

    SELECT ADD_INT(2, 3) AS R FROM RDB$DATABASE

    Aufruf innerhalb von PSQL-Code, der zweite optionale Parameter wird nicht angegeben:

    MY_VAR = ADD_INT(A);
  2. Erstellen einer deterministischen gespeicherten Funktion

    CREATE FUNCTION FN_E()
    RETURNS DOUBLE PRECISION DETERMINISTIC
    AS
    BEGIN
      RETURN EXP(1);
    END
  3. Erstellen einer gespeicherten Funktion mit Parametern vom Typ Tabellenspalte

    Gibt den Namen eines Typs nach Feldname und Wert zurück

    CREATE FUNCTION GET_MNEMONIC (
      AFIELD_NAME TYPE OF COLUMN RDB$TYPES.RDB$FIELD_NAME,
      ATYPE TYPE OF COLUMN RDB$TYPES.RDB$TYPE)
    RETURNS TYPE OF COLUMN RDB$TYPES.RDB$TYPE_NAME
    AS
    BEGIN
      RETURN (SELECT RDB$TYPE_NAME
              FROM RDB$TYPES
              WHERE RDB$FIELD_NAME = :AFIELD_NAME
              AND RDB$TYPE = :ATYPE);
    END
  4. Erstellen einer extern gespeicherten Funktion

    Erstellen Sie eine Funktion, die sich in einem externen Modul (UDR) befindet.Die Funktionsimplementierung befindet sich im externen Modul udrcpp_example.Der Name der Funktion innerhalb des Moduls ist wait_event.

    CREATE FUNCTION wait_event (
      event_name varchar (31) CHARACTER SET ascii
    ) RETURNS INTEGER
    EXTERNAL NAME 'udrcpp_example!Wait_event'
    ENGINE udr
  5. Erstellen einer gespeicherten Funktion mit einer Unterfunktion

    Erstellen einer Funktion zum Konvertieren einer Zahl in das Hexadezimalformat.

    CREATE FUNCTION INT_TO_HEX (
      ANumber BIGINT ,
      AByte_Per_Number SMALLINT = 8)
    RETURNS CHAR (66)
    AS
    DECLARE VARIABLE xMod SMALLINT ;
    DECLARE VARIABLE xResult VARCHAR (64);
    DECLARE FUNCTION TO_HEX (ANum SMALLINT ) RETURNS CHAR
      AS
      BEGIN
        RETURN CASE ANum
          WHEN 0 THEN '0'
          WHEN 1 THEN '1'
          WHEN 2 THEN '2'
          WHEN 3 THEN '3'
          WHEN 4 THEN '4'
          WHEN 5 THEN '5'
          WHEN 6 THEN '6'
          WHEN 7 THEN '7'
          WHEN 8 THEN '8'
          WHEN 9 THEN '9'
          WHEN 10 THEN 'A'
          WHEN 11 THEN 'B'
          WHEN 12 THEN 'C'
          WHEN 13 THEN 'D'
          WHEN 14 THEN 'E'
          WHEN 15 THEN 'F'
          ELSE NULL
        END;
      END
    BEGIN
      xMod = MOD (ANumber, 16);
      ANumber = ANumber / 16;
      xResult = TO_HEX (xMod);
      WHILE (ANUMBER> 0) DO
      BEGIN
        xMod = MOD (ANumber, 16);
        ANumber = ANumber / 16;
        xResult = TO_HEX (xMod) || xResult;
      END
      RETURN '0x' || LPAD (xResult, AByte_Per_Number * 2, '0' );
    END
  6. Wenn DEFINER für die Funktion f gesetzt ist, benötigt der Benutzer US nur das EXECUTE-Privileg auf f.Wenn es auf INVOKER gesetzt wäre, würde der Benutzer auch das INSERT-Privileg für die Tabelle t benötigen.

    set term ^;
    create function f (i integer) returns int SQL SECURITY DEFINER
    as
    begin
      insert into t values (:i);
      return i + 1;
    end^
    set term ;^
    grant execute on function f to user us;
    
    commit;
    
    connect 'localhost:/tmp/59.fdb' user us password 'pas';
    select f(3) from rdb$database;

ALTER FUNCTION

Verwendet für

Ändern einer vorhandenen gespeicherten Funktion

Verfügbar in

DSQL

Syntax
ALTER FUNCTION funcname
  [ ( [ <in_params> ] ) ]
  RETURNS <domain_or_non_array_type> [COLLATE collation]
  [DETERMINISTIC]
  {<psql_function> | <external-module-body>}

!! Vgl. Syntax CREATE FUNCTION für weitere Regeln !!

Die ALTER FUNCTION-Anweisung erlaubt die folgenden Änderungen an einer gespeicherten Funktionsdefinition:

  • der Satz und die Eigenschaften des Eingangs- und Ausgangstyps

  • lokale Variablen, benannte Cursor und Unterprogramme

  • Code im Hauptteil der gespeicherten Prozedur

Für externe Funktionen (UDR) können Sie den Einstiegspunkt und den Engine-Namen ändern.Für ältere externe Funktionen, die mit DECLARE EXTERNAL FUNCTION deklariert wurden – auch als UDFs bekannt – ist es nicht möglich, in PSQL zu konvertieren und umgekehrt.

Nachdem ALTER FUNCTION ausgeführt wurde, bleiben bestehende Privilegien intakt und Abhängigkeiten werden nicht beeinflusst.

Das Ändern einer Funktion ohne Angabe der SQL SECURITY-Klausel entfernt die SQL-Sicherheitseigenschaft, wenn sie derzeit für diese Funktion festgelegt ist.Dies bedeutet, dass das Verhalten auf den Datenbankstandard zurückgesetzt wird.

Caution

Achten Sie darauf, die Anzahl und den Typ der Eingabeparameter und den Ausgabetyp einer gespeicherten Funktion zu ändern.Vorhandener Anwendungscode und Prozeduren, Funktionen und Trigger, die ihn aufrufen, könnten ungültig werden, weil die neue Beschreibung der Parameter nicht mit dem alten Aufrufformat kompatibel ist.Informationen zur Fehlerbehebung in einer solchen Situation finden Sie im Artikel Das RDB$VALID_BLR-Feld im Anhang.

Wer kann eine Funktion ändern

Die ALTER FUNCTION-Anweisung kann ausgeführt werden durch:

  • Administratoren

  • Inhaber der gespeicherten Funktion

  • Benutzer mit der Berechtigung ALTER ANY FUNCTION

Beispiele für ALTER FUNCTION

Ändern einer gespeicherten Funktion
ALTER FUNCTION ADD_INT(A INT, B INT, C INT)
RETURNS INT
AS
BEGIN
  RETURN A + B + C;
END

CREATE OR ALTER FUNCTION

Verwendet für

Erstellen einer neuen oder Ändern einer vorhandenen gespeicherten Funktion

Verfügbar in

DSQL

Syntax
CREATE OR ALTER FUNCTION funcname
  [ ( [ <in_params> ] ) ]
  RETURNS <domain_or_non_array_type> [COLLATE collation]
  [DETERMINISTIC]
  {<psql_function> | <external-module-body>}

!! Vgl. Syntax CREATE FUNCTION für weitere Regeln !!

Die Anweisung CREATE OR ALTER FUNCTION erstellt eine neue gespeicherte Funktion oder ändert eine vorhandene.Wenn die gespeicherte Funktion nicht existiert, wird sie durch transparentes Aufrufen einer CREATE FUNCTION-Anweisung erstellt.Wenn die Funktion bereits existiert, wird sie geändert und kompiliert (durch ALTER FUNCTION), ohne ihre bestehenden Privilegien und Abhängigkeiten zu beeinträchtigen.

Beispiele für CREATE OR ALTER FUNCTION

Erstellen Sie eine neue oder ändern Sie eine vorhandene gespeicherte Funktion
CREATE OR ALTER FUNCTION ADD_INT(A INT, B INT DEFAULT 0)
RETURNS INT
AS
BEGIN
  RETURN A + B;
END

DROP FUNCTION

Verwendet für

Löschen einer gespeicherten Funktion

Verfügbar in

DSQL

Syntax
DROP FUNCTION funcname
Table 1. DROP FUNCTION-Anweisungsparameter
Parameter Beschreibung

funcname

Name der gespeicherten Funktion.Die maximale Länge beträgt 63 Zeichen.Muss unter allen Funktionsnamen in der Datenbank eindeutig sein.

Die DROP FUNCTION-Anweisung löscht eine vorhandene gespeicherte Funktion.Wenn die gespeicherte Funktion Abhängigkeiten aufweist, schlägt der Versuch, sie zu löschen, fehl und der entsprechende Fehler wird ausgegeben.

Wer kann eine Funktion löschen?

Die DROP FUNCTION-Anweisung kann ausgeführt werden durch:

  • Administratoren

  • Inhaber der gespeicherten Funktion

  • Benutzer mit dem Privileg DROP ANY FUNCTION

RECREATE FUNCTION

Verwendet für

Erstellen einer neuen gespeicherten Funktion oder Neuerstellen einer vorhandenen Funktion

Verfügbar in

DSQL

Syntax
RECREATE FUNCTION funcname
  [ ( [ <in_params> ] ) ]
  RETURNS <domain_or_non_array_type> [COLLATE collation]
  [DETERMINISTIC]
  {<psql_function> | <external-module-body>}

!! Vgl. Syntax CREATE FUNCTION für weitere Regeln !!

Die Anweisung 'RECREATE FUNCTION' erstellt eine neue gespeicherte Funktion oder erstellt eine vorhandene neu.Wenn es bereits eine Funktion mit diesem Namen gibt, versucht die Engine, sie zu löschen und dann eine neue zu erstellen.Das Neuerstellen einer vorhandenen Funktion schlägt bei COMMIT fehl, wenn die Funktion Abhängigkeiten hat.

Note

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

Nachdem eine Prozedur erfolgreich neu erstellt wurde, werden vorhandene Berechtigungen zum Ausführen der gespeicherten Funktion und derBerechtigungen der gespeicherten Funktion selbst werden verworfen.

Beispiele für RECREATE FUNCTION

Erstellen oder Wiederherstellen einer gespeicherten Funktion
RECREATE FUNCTION ADD_INT(A INT, B INT DEFAULT 0)
RETURNS INT
AS
BEGIN
  RETURN A + B;
EN