Struktur von PL/pgSQL - Amazon Redshift

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Struktur von PL/pgSQL

PL/pgSQL ist eine prozedurale Sprache mit vielen der gleichen Konstrukte wie andere prozedurale Sprachen.

Block

PL/pgSQL ist eine Sprache in Blockstruktur. Der gesamte Text einer Prozedur ist in einem Block definiert, der variable Deklarationen und PL/pgSQL-Anweisungen enthält. Eine Anweisung kann auch ein verschachtelter Block oder Subblock sein.

Deklarationen und Anweisungen müssen mit einem Doppelpunkt enden. Dem END-Schlüsselwort in einem Block oder Subblock muss ein Doppelpunkt folgen. Verwenden Sie keine Doppelpunkte nach den Schlüsselwörtern DECLARE und BEGIN.

Sie können alle Schlüsselwörter und Kennungen sowohl in Groß- als auch Kleinbuchstaben schreiben. Kennungen werden implizit in Kleinbuchstaben konvertiert, außer sie werden in doppelte Anführungszeichen eingeschlossen.

Ein doppelter Bindestrich (--) beginnt einen Kommentar, der bis zum Ende der Zeile erweitert wird. Ein /* beginnt einen Blockkommentar, der bis zum nächsten Vorkommen von */ erweitert wird. Blockkommentare können nicht verschachtelt werden. Sie können jedoch Kommentare mit doppelten Bindestrichen in einem Blockkommentar einschließen und ein doppelter Bindestrich kann die Blockkommentar-Trennzeichen /* und */ ausblenden.

Jede Anweisung im Anweisungsbereich eines Blocks kann ein Subblock sein. Sie können Subblöcke für die logische Gruppierung oder zum Lokalisieren von Variablen in eine kleine Gruppe von Anweisungen verwenden.

[ <<label>> ] [ DECLARE declarations ] BEGIN statements END [ label ];

Die im Deklarationsbereich vor einem Block deklarierten Variablen werden jedes Mal zu ihren Standardwerten initialisiert, wenn der Block eingegeben wird. Mit anderen Worten, sie werden nicht nur einmal pro Funktionsaufruf initialisiert.

Es folgt ein Beispiel.

CREATE PROCEDURE update_value() AS $$ DECLARE value integer := 20; BEGIN RAISE NOTICE 'Value here is %', value; -- Value here is 20 value := 50; -- -- Create a subblock -- DECLARE value integer := 80; BEGIN RAISE NOTICE 'Value here is %', value; -- Value here is 80 END; RAISE NOTICE 'Value here is %', value; -- Value here is 50 END; $$ LANGUAGE plpgsql;

Verwenden Sie eine Bezeichnung zur Identifizierung des Blocks für eine EXIT-Anweisung oder zur Qualifizierung der Namen der Variablen, die im Block deklariert wurden.

Verwechseln Sie nicht die Verwendung von BEGIN/END für die Gruppierung von Anweisungen in PL/pgSQL mit den Datenbankbefehlen für die Transaktionskontrolle. BEGIN und END dienen in PL/pgSQL lediglich der Gruppierung. Sie beginnen weder eine Transaktion, noch beenden sie eine.

Variablendeklaration

Deklarieren Sie alle Variablen in einem Block, mit Ausnahme der Loop-Variablen, im DECLARE-Bereich des Blocks. Variablen verwenden jeden gültigen Amazon-Redshift-Datentyp. Informationen zu unterstützten Datentypen finden Sie unter Datentypen.

Bei PL/pgSQL-Variablen kann es sich um jeden von Amazon Redshift unterstützten Datentyp handeln sowie RECORD und refcursor. Mehr über RECORD erfahren Sie unter Datensatztypen. Mehr über refcursor erfahren Sie unter Cursor.

DECLARE name [ CONSTANT ] type [ NOT NULL ] [ { DEFAULT | := } expression ];

Im Folgenden finden Sie Beispiele für Variablendeklarationen.

customerID integer; numberofitems numeric(6); link varchar; onerow RECORD;

Die Loop-Variable eines FOR-Loops, die über einen Bereich von Ganzzahlen iteriert, wird automatisch als Ganzzahlvariable deklariert.

Die DEFAULT-Klausel gibt, wenn angegeben, den Anfangswert an, welcher der Variablen beim Eingeben des Blocks zugewiesen wird. Wenn die DEFAULT-Klausel nicht angegeben wird, dann wird die Variable zum SQL-NULL-Wert initialisiert. Die CONSTANT-Option verhindert, dass die Variable zugewiesen wird, sodass ihr Wert für die Dauer des Blocks konstant bleibt. Wenn NOT NULL festgelegt wird, führt eine Zuweisung eines Null-Werts zu einem Laufzeitfehler. Für alle Variablen, die als NOT NULL deklariert sind, muss ein standardmäßiger Nicht-Null-Wert angegeben sein.

Der Standardwert wird bei jeder Eingabe des Blocks ausgewertet. Wenn Sie beispielsweise now() einer Variablen des Typs timestamp zuweisen, weist die Variable den Zeitpunkt des aktuellen Funktionsaufrufs auf und nicht den Zeitpunkt, als die Funktion vorkompiliert wurde.

quantity INTEGER DEFAULT 32; url VARCHAR := 'http://mysite.com'; user_id CONSTANT INTEGER := 10;

Der refcursor-Datentyp ist der Datentyp von Cursor-Variablen in gespeicherten Prozeduren. Ein refcursor-Wert kann von innerhalb einer gespeicherten Prozedur zurückgegeben werden. Weitere Informationen finden Sie unter Rückgabe einer Ergebnismenge aus einer gespeicherten Prozedur.

Aliasdeklaration

Wenn die Signatur der gespeicherten Prozedur den Argumentnamen weg lässt, können Sie einen Alias für das Argument deklarieren.

name ALIAS FOR $n;

Integrierte Variablen

Die folgenden integrierten Variablen werden unterstützt:

  • FOUND

  • SQLSTATE

  • SQLERRM

  • GET DIAGNOSTICS integer_var := ROW_COUNT;

FOUND ist eine spezielle Variable vom Typ Boolesch. FOUND beginnt in jedem Prozeduraufruf mit „false“. FOUND wird von den folgenden Anweisungen festgelegt:

  • SELECT INTO

    Legt FOUND auf „true“ fest, wenn eine Zeile zurückgegeben wird, und auf „false“, wenn keine Zeile zurückgegeben wird.

  • UPDATE, INSERT und DELETE

    Legt FOUND auf „true“ fest, wenn mindestens eine Zeile betroffen ist, und auf „false“, wenn keine Zeile betroffen ist.

  • FETCH

    Legt FOUND auf „true“ fest, wenn eine Zeile zurückgegeben wird, und auf „false“, wenn keine Zeile zurückgegeben wird.

  • FOR-Anweisung

    Legt FOUND auf „true“ fest, wenn die FOR-Anweisung einmal oder mehrmals iteriert, und ansonsten auf „false“. Dies gilt für alle drei Varianten der FOR-Anweisung: Ganzzahl-FOR-Loops, Datensatz-FOR-Loops und dynamische Datensatz-FOR-Loops.

    FOUND wird beim Beenden des FOR-Loops festgelegt. Innerhalb der Laufzeit des Loops wird FOUND nicht von der FOR-Anweisung modifiziert. Es kann jedoch durch die Ausführung anderer Anweisungen im Loop-Text geändert werden.

Es folgt ein Beispiel.

CREATE TABLE employee(empname varchar); CREATE OR REPLACE PROCEDURE show_found() AS $$ DECLARE myrec record; BEGIN SELECT INTO myrec * FROM employee WHERE empname = 'John'; IF NOT FOUND THEN RAISE EXCEPTION 'employee John not found'; END IF; END; $$ LANGUAGE plpgsql;

Innerhalb eines Ausnahmehandlers enthält die spezielle Variable SQLSTATE den Fehlercode, welcher der Ausnahme entspricht, die ausgelöst wurde. Die spezielle Variable SQLERRM enthält die mit der Ausnahme verbundene Fehlermeldung. Diese Variablen sind außerhalb von Ausnahmehandlern undefiniert und zeigen bei Verwendung einen Fehler an.

Es folgt ein Beispiel.

CREATE OR REPLACE PROCEDURE sqlstate_sqlerrm() AS $$ BEGIN UPDATE employee SET firstname = 'Adam' WHERE lastname = 'Smith'; EXECUTE 'select invalid'; EXCEPTION WHEN OTHERS THEN RAISE INFO 'error message SQLERRM %', SQLERRM; RAISE INFO 'error message SQLSTATE %', SQLSTATE; END; $$ LANGUAGE plpgsql;

ROW_COUNT wird mit dem Befehl GET DIAGNOSTICS verwendet. Sie zeigt die Anzahl der Spalten an, die vom letzten SQL-Befehl verarbeitet wurden, der an die SQL-Engine gesendet wurde.

Es folgt ein Beispiel.

CREATE OR REPLACE PROCEDURE sp_row_count() AS $$ DECLARE integer_var int; BEGIN INSERT INTO tbl_row_count VALUES(1); GET DIAGNOSTICS integer_var := ROW_COUNT; RAISE INFO 'rows inserted = %', integer_var; END; $$ LANGUAGE plpgsql;

Datensatztypen

Ein RECORD-Typ ist kein echter Datensatztyp, sondern nur ein Platzhalter. Variablen vom Datensatztyp übernehmen die tatsächliche Zeilenstruktur der Zeile, der sie während des SELECT- oder FOR-Befehls zugeordnet werden. Die Unterstruktur einer Datensatzvariablen kann sich bei jeder Zuordnung zu einem Wert ändern. Eine Datensatzvariable verfügt erst dann über eine Unterstruktur, wenn sie zum ersten Mal zugewiesen wird. Bei jedem Versuch auf ein darin enthaltenes Feld zuzugreifen, wird ein Laufzeitfehler zurückgegeben.

name RECORD;

Es folgt ein Beispiel.

CREATE TABLE tbl_record(a int, b int); INSERT INTO tbl_record VALUES(1, 2); CREATE OR REPLACE PROCEDURE record_example() LANGUAGE plpgsql AS $$ DECLARE rec RECORD; BEGIN FOR rec IN SELECT a FROM tbl_record LOOP RAISE INFO 'a = %', rec.a; END LOOP; END; $$;