Для чего используются '$$' в PL / pgSQL

98

Будучи совершенно новым для PL / pgSQL, что означают двойные знаки доллара в этой функции :

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;

Я предполагаю , что, в RETURNS boolean AS $$, $$является заполнителем.

Последняя строчка немного загадочна: $$ LANGUAGE plpgsql STRICT IMMUTABLE;

Кстати, а что означает последняя строчка?

вектор
источник
4
Пожалуйста, пометьте ответ Эрвина как ответ на этот вопрос, его описание объясняет, что на самом деле есть, $$и вы можете узнать что-то новое, прочитав его, например, есть также$foo$
csharpfolk

Ответы:

143

Знаки доллара используются для обозначения доллара и никоим образом не относятся к определениям функций . Его можно использовать для замены одинарных кавычек практически в любом месте сценариев SQL.

Тело функции представляет собой строковый литерал, который нужно заключить в одинарные кавычки. Цитирование в долларах - это специфическая для PostgreSQL замена одинарных кавычек, позволяющая избежать проблем с кавычками внутри тела функции. Вы также можете написать определение своей функции в одинарных кавычках. Но тогда вам придется избегать одинарных кавычек в теле:

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;

Это не такая уж хорошая идея. Вместо этого $$используйте долларовые кавычки , а точнее также поместите токен между, чтобы сделать его уникальным - вы также можете использовать $ -квоты внутри тела функции. На самом деле, я делаю это очень часто.

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

Детали:

Что касается вашего второго вопроса:
прочтите прекраснейшее руководство,CREATE FUNCTION чтобы понять последнюю строку вашего примера.

Эрвин Брандштеттер
источник
1
Вы должны сказать « прекрасное руководство» , у RTEM просто нет нужного звонка :)
mu слишком короткое
@muistooshort: Плохо, но попытка вариации на тему, кажется, нарушила гармонию. Как тебе РТМЭМ? :)
Эрвин Брандштеттер
1
Я пробовал кричать, но это было не то. Хотя бывают ситуации, когда вежливость имеет значение.
mu слишком короткий
@ErwinBrandstetter Хорошо, но что $body$? От CREATE OR REPLACE FUNCTION update_ts() RETURNS TRIGGER AS $BODY$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $BODY$ LANGUAGE plpgsql- bodyнигде не вижу определения. Я действительно понятия не имею, что здесь происходит
Growler
2
@Growler: $body$это просто " котировка доллара", как я объяснил. Подробнее: stackoverflow.com/a/12320729/939860
Эрвин Брандштеттер
21

$$ - это разделитель, который вы используете, чтобы указать, где начинается и заканчивается определение функции. Рассмотрим следующее:

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

Синтаксис функции создания аналогичен, но поскольку вы собираетесь использовать в своей функции все виды SQL (особенно символ конца оператора), синтаксический анализатор отключится, если вы не ограничите его. Итак, вы должны читать свое утверждение как:

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

Материал после фактического определения - это параметры, позволяющие предоставить базе данных больше информации о вашей функции, чтобы она могла оптимизировать ее использование.

Фактически, если вы посмотрите в разделе «4.1.2.2. Строковые константы, выраженные в долларах» в руководстве, вы увидите, что вы даже можете использовать символы между символами доллара, и все это будет считаться одним разделителем.

Капитан Кодер
источник