A cosa servono '$$' in PL / pgSQL


93

Essendo completamente nuovo a PL / pgSQL, qual è il significato dei segni del doppio dollaro in questa funzione :

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;

Immagino che, in RETURNS boolean AS $$, $$sia un segnaposto.

L'ultima riga è un po 'un mistero: $$ LANGUAGE plpgsql STRICT IMMUTABLE;

A proposito, cosa significa l'ultima riga?


4
Per favore considera la possibilità di contrassegnare la risposta di Erwin come risposta a questa domanda, la sua descrizione spiega cosa sono effettivamente $$e puoi imparare qualcosa di nuovo leggendolo, ad esempio c'è anche$foo$
csharpfolk

Risposte:


135

I segni del dollaro vengono utilizzati per la quotazione del dollaro e non sono in alcun modo specifici per le definizioni di funzione . Può essere utilizzato per sostituire le virgolette singole praticamente ovunque negli script SQL.

Il corpo di una funzione sembra essere una stringa letterale che deve essere racchiusa tra virgolette singole. La quotazione in dollari è un sostituto specifico di PostgreSQL per le virgolette singole per evitare problemi di quotazione all'interno del corpo della funzione. Puoi anche scrivere la definizione della tua funzione con virgolette singole. Ma poi dovresti sfuggire a tutte le virgolette singole nel corpo:

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;

Questa non è una buona idea. Usa invece le $$virgolette in dollari , più specificamente inserisci anche un token tra per renderlo unico: potresti anche voler usare $ -quotes all'interno del corpo della funzione. Lo faccio spesso, in realtà.

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

Dettagli:

Per quanto riguarda la seconda domanda:
leggi il manualeCREATE FUNCTION più eccellente per capire l'ultima riga del tuo esempio.


1
Dovresti dire che il manuale va bene , RTEM non ha la suoneria giusta :)
mu è troppo breve

@muistooshort: Colpa mia, provare una variazione sul tema sembra aver rotto l'armonia. Come ti piace RTMEM? :)
Erwin Brandstetter

1
Ho provato a gridare e non era la stessa cosa. Tuttavia, ci sono alcune situazioni in cui la cortesia conta.
mu è troppo breve il

@ErwinBrandstetter Va bene, ma cos'è $body$? Da CREATE OR REPLACE FUNCTION update_ts() RETURNS TRIGGER AS $BODY$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $BODY$ LANGUAGE plpgsql- non vedo bodydefinito da nessuna parte. Non ho davvero idea di cosa stia succedendo qui
Growler

2
@Growler: $body$è solo "quotazione del dollaro", come ho spiegato. Maggiori dettagli: stackoverflow.com/a/12320729/939860
Erwin Brandstetter

21

$$ è un delimitatore utilizzato per indicare dove inizia e finisce la definizione della funzione. Considera quanto segue,

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

La sintassi della funzione di creazione è simile, ma poiché utilizzerai tutti i tipi di SQL nella tua funzione (specialmente la fine dell'istruzione; carattere), il parser scatta se non lo delimiti. Quindi dovresti leggere la tua dichiarazione come:

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

Le cose dopo la definizione effettiva sono opzioni per fornire al database maggiori informazioni sulla tua funzione, in modo che possa ottimizzarne l'utilizzo.

Infatti, se guardi sotto "4.1.2.2. Costanti stringa quotate in dollari" nel manuale, vedrai che puoi persino usare caratteri tra i simboli del dollaro e tutto conterà come un delimitatore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.