À quoi sert '$$' dans PL / pgSQL

93

Étant complètement nouveau dans PL / pgSQL, quelle est la signification des signes double dollar dans cette fonction :

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;

Je suppose que, dans RETURNS boolean AS $$, $$est un espace réservé.

La dernière ligne est un peu mystérieuse: $$ LANGUAGE plpgsql STRICT IMMUTABLE;

Au fait, que signifie la dernière ligne?

vecteur
la source
4
Veuillez envisager de marquer la réponse d'Erwin comme réponse à cette question, sa description explique ce que sont réellement $$et vous pouvez apprendre quelque chose de nouveau en la lisant, par exemple il y a aussi$foo$
csharpfolk

Réponses:

135

Les signes dollar sont utilisés pour les cotations en dollars et ne sont en aucun cas spécifiques aux définitions de fonction . Il peut être utilisé pour remplacer les guillemets simples pratiquement n'importe où dans les scripts SQL.

Le corps d'une fonction se trouve être une chaîne littérale qui doit être placée entre guillemets simples. Les guillemets en dollars sont un substitut spécifique à PostgreSQL pour les guillemets simples pour éviter les problèmes de citation à l'intérieur du corps de la fonction. Vous pouvez également écrire la définition de votre fonction avec des guillemets simples. Mais alors vous devrez échapper à tous les guillemets simples dans le corps:

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;

Ce n'est pas une si bonne idée. Utilisez plutôt des guillemets en dollars, plus spécifiquement, placez également un jeton entre les $$pour le rendre unique - vous pouvez également utiliser des guillemets $ dans le corps de la fonction. Je fais beaucoup ça, en fait.

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

Détails:

Quant à votre deuxième question:
lisez le plus excellent manuelCREATE FUNCTION pour comprendre la dernière ligne de votre exemple.

Erwin Brandstetter
la source
1
Vous êtes censé dire un bon manuel , RTEM n'a tout simplement pas la bonne sonnerie :)
mu est trop court
@muistooshort: Mon mal, essayer une variation sur le thème semble avoir rompu l'harmonie. Comment aimez-vous RTMEM? :)
Erwin Brandstetter
1
J'ai essayé de le crier et ce n'était tout simplement pas la même chose. Cependant, il existe des situations où la politesse compte.
mu est trop court
@ErwinBrandstetter D'accord, mais qu'est-ce que c'est $body$? De CREATE OR REPLACE FUNCTION update_ts() RETURNS TRIGGER AS $BODY$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $BODY$ LANGUAGE plpgsql- je ne vois bodydéfini nulle part. Je n'ai vraiment aucune idée de ce qui se passe ici
Growler
2
@Growler: $body$c'est juste une "cotation en dollars", comme je l'ai expliqué. Plus de détails: stackoverflow.com/a/12320729/939860
Erwin Brandstetter
21

Le $$ est un délimiteur que vous utilisez pour indiquer le début et la fin de la définition de fonction. Considérer ce qui suit,

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

La syntaxe de la fonction de création est similaire, mais comme vous allez utiliser toutes sortes de SQL dans votre fonction (en particulier la fin de l'instruction; caractère), l'analyseur se déclenche si vous ne la délimitez pas. Vous devriez donc lire votre déclaration comme suit:

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

Les éléments après la définition réelle sont des options pour donner à la base de données plus d'informations sur votre fonction, afin qu'elle puisse optimiser son utilisation.

En fait, si vous regardez sous "4.1.2.2. Constantes de chaîne à guillemets en dollars" dans le manuel, vous verrez que vous pouvez même utiliser des caractères entre les symboles du dollar et tout cela comptera comme un délimiteur.

Capitaine Coder
la source