Для чого використовуються "$$" в PL / pgSQL


93

Будучи абсолютно новим для 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

Відповіді:


135

Знаки долара використовуються для котирування долара і жодним чином не є специфічними для визначень функцій . Він може бути використаний для заміни одинарних лапок практично де завгодно в сценаріях 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;

Це не така гарна ідея. Замість цього використовуйте котирування долара, точніше також поставте маркер між, $$щоб зробити його унікальним - можливо, ви захочете використовувати $ -quotes і всередині тіла функції. Насправді я так багато роблю.

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: Моя погана спроба змінити тему, здається, порушила гармонію. Як вам RTMEM? :)
Ервін Брандштеттер

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 02

2
@Growler: $body$це просто "котирування доларів", як я вже пояснив. Детальніше: stackoverflow.com/a/12320729/939860
Ервін Брандштеттер

21

$$ - це роздільник, за допомогою якого ви вказуєте, де визначення функції починається та закінчується. Розглянемо наступне:

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

Синтаксис функції create подібний, але оскільки ви збираєтеся використовувати всілякі SQL у своїй функції (особливо кінець оператора; символ), парсер спрацює, якщо ви не розмежуєте його. Тож ви повинні читати свою заяву як:

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

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

Насправді, якщо ви подивитесь на "4.1.2.2. Рядові константи, вказані в доларах" у посібнику, ви побачите, що ви навіть можете використовувати символи між символами долара, і все це буде враховуватися як один роздільник.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.