118

对于 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;

我猜, inRETURNS boolean AS $$$$一个占位符。

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

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

4

2 回答 2

175

这些美元符号 ( $$) 用于美元报价,这绝不是特定于函数定义的。它可用于替换 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以了解您示例的最后一行。

于 2012-08-29T06:54:07.020 回答
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. Dollar-Quoted String Constants”,您会发现您甚至可以在美元符号之间使用字符,并且它们都将被视为一个分隔符。

于 2012-08-27T15:21:04.080 回答