Skip to content

43.2.PL/pgSQL的结构#

用PL/pgSQL编写的函数通过执行CREATE FUNCTION命令向服务器定义。此类命令通常看起来像,例如:

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

CREATE FUNCTION而言,函数正文只是一个字符串文字。通常,使用美元引用(请参阅第 4.1.2.4 节)来编写函数正文,而不是使用普通的单引号语法,这通常很有帮助。如果不使用美元引用,函数正文中的任何单引号或反斜杠都必须通过加倍来转义。本章中的几乎所有示例都使用美元引用文字作为其函数正文。

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

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

块中的每个声明和每个语句都以分号结尾。出现在另一个块中的块必须在END后面有一个分号,如上所示;但是,结束函数正文的最终END不需要分号。

提示

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

只有在您想要识别块以用于EXIT语句中,或限定块中声明的变量的名称时,才需要*标签*。如果在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;
    --
    -- Create a subblock
    --
    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;

注意

实际上,任何PL/pgSQL函数的主体周围都有一个隐藏的“外部块”。此块提供函数参数(如果有)的声明,以及一些特殊变量,例如FOUND(请参见第 43.5.5 节)。外部块标记为函数的名称,这意味着参数和特殊变量可以使用函数的名称限定。

重要的是不要将PL/pgSQL中的BEGIN/END用于分组语句与用于事务控制的同名 SQL 命令混淆。PL/pgSQL的BEGIN/END仅用于分组;它们不会开始或结束事务。有关在PL/pgSQL中管理事务的信息,请参见第 43.8 节。此外,包含EXCEPTION子句的块有效地形成一个子事务,该子事务可以在不影响外部事务的情况下回滚。有关更多信息,请参见第 43.6.8 节