受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

41.2. PL/pgSQL的结构 #

通过执行 CREATE FUNCTION 命令,可以把用 PL/pgSQL 编写的函数定义到服务器中。这类命令通常类似于:

CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'function body text'
LANGUAGE plpgsql;

CREATE FUNCTION 而言,函数体目前只是一个字符串字面量。编写函数体时,通常最好使用美元引用(见 Section 4.1.2.4),而不是普通的单引号语法。如果不使用美元引用,函数体中的任何单引号或反斜线都必须通过双写进行转义。本章几乎所有示例的函数体都使用了美元引用。

PL/pgSQL 是一种块结构语言。函数体的完整文本必须是一个。块的定义如下:

[ <<label>> ]
[ DECLARE
    declarations ]
BEGIN
    statements
END [ label ];

块中的每个声明和每条语句都以分号结束。如上所示,嵌套在其他块中的块,必须在 END 之后写分号;但是结束整个函数体的最后一个 END 不需要分号。

Tip

一个常见错误是在 BEGIN 后面立刻写分号。这是不正确的,并会导致语法错误。

只有在你希望通过 EXIT 语句标识某个块,或者希望用块名限定块内声明的变量名时,才需要 label。如果在 END 之后写了标签,它必须与块开始处的标签一致。

所有关键字都不区分大小写。标识符除非用双引号括起,否则会像普通 SQL 命令中那样被隐式转换为小写。

PL/pgSQL 代码中的注释与普通 SQL 相同。双连字符(--)开始一段持续到行尾的注释。/* 开始一段块注释,它会持续到匹配的 */。块注释可以嵌套。

块的语句部分中的任意语句都可以是一个子块。子块可用于逻辑分组,或者把变量局部化到一小组语句中。在子块存续期间,子块中声明的变量会遮蔽外层块中的同名变量。不过,如果使用块标签限定外层变量名,仍然可以访问它们。例如:

CREATE FUNCTION somefunc() RETURNS integer AS $$
<< outerblock >>
DECLARE
    quantity integer := 30;
BEGIN
    RAISE NOTICE 'Quantity here is %', quantity;  -- Prints 30
    quantity := 50;
    --
    -- 创建一个子块
    --
    DECLARE
        quantity integer := 80;
    BEGIN
        RAISE NOTICE 'Quantity here is %', quantity;  -- Prints 80
        RAISE NOTICE 'Outer quantity here is %', outerblock.quantity;  -- Prints 50
    END;

    RAISE NOTICE 'Quantity here is %', quantity;  -- Prints 50

    RETURN quantity;
END;
$$ LANGUAGE plpgsql;

Note

实际上,任何 PL/pgSQL 函数体外面都包着一个隐藏的外层块。该块提供函数参数(如果有)的声明,以及一些诸如 FOUND 之类的特殊变量(见 Section 41.5.5)。这个外层块带有函数名标签,这意味着参数和特殊变量可以用函数名来限定。

需要特别注意,不要把 PL/pgSQL 中用于分组语句的 BEGIN/END 与用于事务控制的同名 SQL 命令混淆。PL/pgSQL 中的 BEGIN/END 只用于分组,不会开始或结束事务。关于在 PL/pgSQL 中管理事务的信息,参见 Section 41.8。另外,包含 EXCEPTION 子句的块实际上会形成一个可回滚而不影响外层事务的子事务。详见 Section 41.6.8

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。