什么是'$$'用于PL/pgSQL

vec*_*tor 82 postgresql quotes plpgsql dollar-sign dollar-quoting

作为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;
Run Code Online (Sandbox Code Playgroud)

我猜,在RETURNS boolean AS $$,$$是一个占位符.

最后一行有点神秘: $$ LANGUAGE plpgsql STRICT IMMUTABLE;

顺便说一句,最后一行是什么意思?

Erw*_*ter 116

美元符号用于美元报价,并不特定于函数定义.它几乎可以用于替换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;
Run Code Online (Sandbox Code Playgroud)

这不是一个好主意.相反,使用美元引用,更具体地说,还要在$$它之间放置一个令牌以使其唯一 - 您可能也想在函数体内使用$ -quotes.实际上,我做了很多.

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

细节:

至于你的第二个问题:
阅读最优秀的手册CREATE FUNCTION,了解你的例子的最后一行.

  • 你应该说“很好的手册”,RTEM 只是没有合适的戒指:) (3认同)
  • @Growler:`$ body $`只是"引用美元",就像我解释的那样.更多细节:http://stackoverflow.com/a/12320729/939860 (2认同)

Cap*_*der 19

$$是一个分隔符,用于指示函数定义的开始和结束位置.考虑以下,

CREATE TABLE <name> <definition goes here> <options go here, eg: WITH OIDS>
Run Code Online (Sandbox Code Playgroud)

create function语法类似,但是因为你要在你的函数中使用各种SQL(特别是语句的结尾;字符),如果你没有分隔它,解析器就会跳转.所以你应该把你的陈述读作:

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

实际定义之后的内容是为数据库提供有关函数的更多信息的选项,因此可以优化其用法.

事实上,如果你看一下手册中的"4.1.2.2.美元引用的字符串常量",你会发现你甚至可以在美元符号之间使用字符,它们都算作一个分隔符.