Wofür wird '$$' in PL / pgSQL verwendet?

92

Da PL / pgSQL völlig neu ist, was bedeuten doppelte Dollarzeichen in dieser Funktion :

CREATE OR REPLACE FUNCTION check_phone_number(text)
RETURNS boolean AS $$
BEGIN
  IF NOT $1 ~  e'^\\+\\d{3}\\ \\d{3} \\d{3} \\d{3}$' THEN
    RAISE EXCEPTION 'Wrong formated string "%". Expected format is +999 999';
  END IF;
  RETURN true; 
END;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;

Ich vermute , dass, in RETURNS boolean AS $$, $$ist ein Platzhalter.

Die letzte Zeile ist ein bisschen rätselhaft: $$ LANGUAGE plpgsql STRICT IMMUTABLE;

Was bedeutet übrigens die letzte Zeile?

Vektor
quelle
4
Bitte erwägen Sie, Erwins Antwort als Antwort auf diese Frage zu markieren. Seine Beschreibung erklärt, was tatsächlich ist, $$und Sie können etwas Neues lernen, indem Sie es lesen, z. B. gibt es auch$foo$
csharpfolk

Antworten:

135

Die Dollarzeichen werden für Dollarnotierungen verwendet und sind in keiner Weise spezifisch für Funktionsdefinitionen . Es kann verwendet werden, um einfache Anführungszeichen praktisch überall in SQL-Skripten zu ersetzen.

Der Hauptteil einer Funktion ist zufällig ein Zeichenfolgenliteral, das in einfache Anführungszeichen gesetzt werden muss. Dollar-Quoting ist ein PostgreSQL-spezifischer Ersatz für einfache Anführungszeichen, um Anführungszeichenprobleme innerhalb des Funktionskörpers zu vermeiden. Sie können Ihre Funktionsdefinition auch in einfache Anführungszeichen schreiben. Aber dann müssten Sie allen einfachen Anführungszeichen im Körper entkommen:

CREATE OR REPLACE FUNCTION check_phone_number(text)
RETURNS boolean AS
'
BEGIN
  IF NOT $1 ~  e''^\\+\\d{3}\\ \\d{3} \\d{3} \\d{3}$'' THEN
    RAISE EXCEPTION ''Malformed string "%". Expected format is +999 999'';
  END IF;
  RETURN true; 
END
' LANGUAGE plpgsql STRICT IMMUTABLE;

Das ist keine so gute Idee. Verwenden Sie stattdessen Dollar-Anführungszeichen, und setzen Sie insbesondere ein Token zwischen die $$Anführungszeichen, um es eindeutig zu machen. Möglicherweise möchten Sie auch $ -Zitate im Funktionskörper verwenden. Das mache ich eigentlich viel.

CREATE OR REPLACE FUNCTION check_phone_number(text)
  RETURNS boolean  
AS
$func$
BEGIN
 ...
END
$func$  LANGUAGE plpgsql STRICT IMMUTABLE;

Einzelheiten:

Zu Ihrer zweiten Frage:
Lesen Sie das beste HandbuchCREATE FUNCTION , um die letzte Zeile Ihres Beispiels zu verstehen.

Erwin Brandstetter
quelle
1
Du solltest sagen, feines Handbuch , RTEM hat einfach nicht den richtigen Klang :)
mu ist zu kurz
@ Muistooshort: Mein schlechtes, eine Variation des Themas zu versuchen, scheint die Harmonie gebrochen zu haben. Wie gefällt dir RTMEM? :)
Erwin Brandstetter
1
Ich habe versucht, es zu schreien und es war einfach nicht dasselbe. Es gibt jedoch Situationen, in denen Höflichkeit zählt.
Mu ist zu kurz
@ErwinBrandstetter Okay, aber was ist $body$? Von CREATE OR REPLACE FUNCTION update_ts() RETURNS TRIGGER AS $BODY$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $BODY$ LANGUAGE plpgsql- Ich sehe bodynirgendwo definiert. Ich habe wirklich keine Ahnung, was hier los ist
Growler
2
@Growler: $body$ist nur "Dollar-Quoting", wie ich erklärt habe. Weitere Details: stackoverflow.com/a/12320729/939860
Erwin Brandstetter
20

Das $$ ist ein Trennzeichen, mit dem Sie angeben, wo die Funktionsdefinition beginnt und endet. Folgendes berücksichtigen,

CREATE TABLE <name> <definition goes here> <options go here, eg: WITH OIDS>

Die Syntax der Erstellungsfunktion ist ähnlich, aber da Sie in Ihrer Funktion alle Arten von SQL verwenden (insbesondere das Ende der Anweisung; Zeichen), würde der Parser auslösen, wenn Sie ihn nicht abgrenzen. Sie sollten Ihre Aussage also wie folgt lesen:

CREATE OR REPLACE FUNCTION check_phone_number(text)
RETURNS boolean AS <code delimited by $$> LANGUAGE plpgsql STRICT IMMUTABLE;

Das Zeug nach der eigentlichen Definition sind Optionen, um der Datenbank mehr Informationen über Ihre Funktion zu geben, damit sie ihre Verwendung optimieren kann.

Wenn Sie im Handbuch unter "4.1.2.2. String-Konstanten in Dollar-Anführungszeichen" nachsehen, werden Sie feststellen, dass Sie sogar Zeichen zwischen den Dollar-Symbolen verwenden können und alles als ein Trennzeichen zählt.

Kapitän Coder
quelle