“ $$”在 PL/pgSQL 中的用途是什么

作为 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;

顺便问一下,最后一行是什么意思?

60944 次浏览

$$是用来指示函数定义开始和结束位置的分隔符,

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.4. 美元报价字符串常数”,您将看到您甚至可以在美元符号之间使用字符,并且它将全部计为一个分隔符。

这些美元符号($$)用于 美元报价,即 没有特定于函数定义的方式。它可以用来替换 SQL 脚本中任何地方包含字符串文字(常量)的单引号。

函数体正好是这样一个字符串文字。Dollar-quoting 是 PostgreSQL 特定的单引号替代品,以避免(递归地)转义嵌套的单引号。也可以将函数体用单引号括起来。但是你必须避开正文中所有的单引号:

CREATE OR REPLACE FUNCTION check_phone_number(text)
RETURNS boolean
LANGUAGE plpgsql STRICT IMMUTABLE 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
';

这不是个好主意。用美元报价代替。更具体地说,还要在 $$之间放置一个令牌,以使每一对都是唯一的——您可能希望在函数体中使用嵌套的美元引号。事实上,我经常这么做。

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

参见:

至于你的第二个问题:
阅读最优秀的 CREATE FUNCTION手册来理解示例的最后一行。