# 43.2.PL/pgSQL的结构

用PL/pgSQL编写的函数通过执行创建函数命令。这样的命令通常看起来像,

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

函数体只是一个字符串文字创建函数他很担心。使用美元报价通常很有帮助(参见第4.1.2.4节)编写函数体,而不是普通的单引号语法。在没有美元报价的情况下,函数体中的任何单引号或反斜杠都必须通过加倍来避免。本章中的几乎所有示例都使用美元引用的文字作为其函数体。

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

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

块中的每个声明和语句都以分号结尾。出现在另一个块中的块后面必须有分号终止,如上所示;然而决赛终止这意味着函数体不需要分号。

# 提示

一个常见的错误是在后面立即写分号开始。这是不正确的,将导致语法错误。

A.*标签*仅当您要标识块以便在应用程序中使用时才需要出口语句,或限定块中声明的变量的名称。如果标签是在终止,它必须与块开头的标签匹配。

所有关键字都不区分大小写。标识符隐式转换为小写,除非双引号,就像在普通SQL命令中一样。

注释在PL/pgSQL代码中的工作方式与在普通SQL中的工作方式相同。双短跑(--)开始一条延伸到行尾的注释。A./*开始一个块注释,扩展到匹配的*/.阻止评论。

块的语句部分中的任何语句都可以是子块.子块可用于逻辑分组或将变量本地化为一小组语句。子块中声明的变量在子块期间屏蔽外部块的任何类似命名变量;但是,如果用块的标签限定外部变量的名称,则可以访问它们。例如:

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函数的主体周围都有一个隐藏的“外部块”。此块提供函数参数(如果有)的声明,以及一些特殊变量,如建立(见第43.5.5节).外部块标有函数名,这意味着参数和特殊变量可以用函数名限定。

重要的是不要混淆开始/终止用于将PL/pgSQL中的语句与用于事务控制的类似SQL命令进行分组。PL/pgSQL开始/终止仅用于分组;他们不会开始或结束交易。看见第43.8节有关在PL/pgSQL中管理事务的信息。此外,一个包含例外子句有效地形成了一个子事务,可以在不影响外部事务的情况下回滚。有关更多信息,请参见第43.6.8节.