¿Para que se usan '$$' en PL / pgSQL

93

Siendo completamente nuevo en PL / pgSQL, ¿cuál es el significado de los signos de dólar dobles en esta función ?

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;

Supongo que, en RETURNS boolean AS $$, $$es un marcador de posición.

La última línea es un poco misteriosa: $$ LANGUAGE plpgsql STRICT IMMUTABLE;

Por cierto, ¿qué significa la última línea?

vector
fuente
4
Considere marcar la respuesta de Erwin como respuesta a esta pregunta, su descripción explica lo que realmente son $$y puede aprender algo nuevo leyéndolo, por ejemplo, también hay$foo$
csharpfolk

Respuestas:

135

Los signos de dólar se utilizan para cotizar en dólares y no son específicos de las definiciones de funciones . Se puede utilizar para reemplazar comillas simples prácticamente en cualquier lugar de los scripts SQL.

El cuerpo de una función es un literal de cadena que debe estar entre comillas simples. Dollar-quoting es un sustituto específico de PostgreSQL para las comillas simples para evitar problemas de citas dentro del cuerpo de la función. También puede escribir la definición de su función con comillas simples. Pero luego tendrías que escapar de todas las comillas simples en el cuerpo:

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;

No es tan buena idea. En su lugar, use la cotización en dólares, más específicamente también coloque un token entre $$para que sea única; es posible que también desee usar $ -quotes dentro del cuerpo de la función. De hecho, hago mucho eso.

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

Detalles:

En cuanto a su segunda pregunta:
lea el manualCREATE FUNCTION más excelente para comprender la última línea de su ejemplo.

Erwin Brandstetter
fuente
1
Se supone que debes decir buen manual , RTEM simplemente no tiene el tono correcto :)
mu es demasiado corto
@muistooshort: Mi mal, intentar una variación del tema parece haber roto la armonía. ¿Qué te parece RTMEM? :)
Erwin Brandstetter
1
Intenté gritarlo y no fue lo mismo. Sin embargo, hay algunas situaciones en las que la cortesía cuenta.
mu es demasiado corto
@ErwinBrandstetter Está bien, pero ¿qué es $body$? Desde CREATE OR REPLACE FUNCTION update_ts() RETURNS TRIGGER AS $BODY$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $BODY$ LANGUAGE plpgsql- no veo bodydefinido en ningún lado. Realmente no tengo idea de lo que está pasando aquí
Growler
2
@Growler: $body$es solo "cotización en dólares", como expliqué. Más detalles: stackoverflow.com/a/12320729/939860
Erwin Brandstetter
21

$$ es un delimitador que se usa para indicar dónde comienza y termina la definición de la función. Considera lo siguiente,

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

La sintaxis de la función de creación es similar, pero debido a que va a usar todo tipo de SQL en su función (especialmente el final de la declaración; carácter), el analizador se disparará si no lo delimita. Por lo tanto, debe leer su declaración como:

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

Lo que sigue a la definición real son opciones para dar a la base de datos más información sobre su función, para que pueda optimizar su uso.

De hecho, si mira en "4.1.2.2. Constantes de cadena entre comillas en dólares" en el manual, verá que incluso puede usar caracteres entre los símbolos de dólares y todo contará como un delimitador.

Capitán Codificador
fuente