用 PL/pgSQL 编写的函数是通过执行 CREATE FUNCTION 命令向服务器定义的。 这样一条命令通常看起来像这样:
CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'function body text'
LANGUAGE plpgsql;
就 CREATE FUNCTION 而言,函数体只是一个字符串字面值。
使用美元符引用(见 Section 4.1.2.4)
来书写函数体通常比使用普通的单引号语法更有帮助。如果不使用美元符引用,
函数体中的任何单引号或反斜线都必须通过加倍来转义。
本章几乎所有示例的函数体都使用美元符引用的字面值。
PL/pgSQL 是一种块结构语言。 函数体的完整文本必须是一个块。 块的定义如下:
[ <<label>> ] [ DECLAREdeclarations] BEGINstatementsEND [label];
块中的每条声明和每条语句都以分号结束。出现在另一个块中的块
必须在 END 后面有分号,如上所示;
然而结束函数体的最后一个 END 不需要分号。
一个常见的错误是在 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;
--
-- 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(见
Section 41.5.5)。
外层块以函数名作为标签,这意味着参数和特殊变量
可以用函数名进行限定。
务必不要把 PL/pgSQL 中用于语句分组的
BEGIN/END
与名称相似的 SQL 事务控制命令混淆。PL/pgSQL
的 BEGIN/END
只用于分组;它们不会开始或结束事务。
有关在 PL/pgSQL 中管理事务的信息,
参见 Section 41.8。
另外,包含 EXCEPTION 子句的块实际上会形成一个子事务,
它可以被回滚而不影响外层事务。更多相关信息见 Section 41.6.8。