ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 40.1\. 概述 PL/pgSQL是PostgreSQL数据库系统的一个可加载的过程语言。 PL/pgSQL的设计目标是创建一种可加载的过程语言,可以 * 用于创建函数和触发器过程, * 为SQL语言增加控制结构, * 执行复杂的计算, * 继承所有用户定义类型、函数、操作符, * 定义为被服务器信任的语言, * 容易使用。 PL/pgSQL创建的函数可以在那些使用内置函数一样的情形下使用。 比如,可以创建复杂的条件计算函数,并随后将之用于定义操作符或者用于函数索引中。 在PostgreSQL 9.0及其之后的版本中,PL/pgSQL是默认安装的。 当然,PL/pgSQL仍然是一个可加载的模块,因此,如果实际安全需要,管理员也可以选择将它卸载掉。 ## 40.1.1\. 使用PL/pgSQL的优点 SQL是PostgreSQL和大多数其它关系型数据库的命令语言。 它是可移植的,并且容易学习使用。但是所有SQL语句都必须由数据库服务器独立地执行。 这就意味着你的客户端应用必须把每条命令发送到数据库服务器, 等待它处理这个命令,接收结果,对结果进行一些处理, 然后再给服务器发送另外一条命令。 所有这些东西都会产生进程间通讯, 并且如果你的客户端在另外一台机器上甚至还会产生网络开销。 通过PL/pgSQL,可以把运算块和一系列命令在数据库服务器_内部_组成一个块, 这样就拥有了过程语言的能力并且简化 SQL 的使用, 因而节约了大量的时间,因为不需要进行客户端/服务器通讯。 * 忽略了客户端和服务器端之间的额外往返行程。 * 客户端不需要的中间结果无需在服务器端和客户端来回传递。 * 不需要多次语法分析步骤。 比起不使用存储函数来,这样做能够产生明显的性能提升。 同样,在PL/pgSQL里,仍然可以使用SQL的所有数据类型,操作符和函数。 ## 40.1.2\. 支持的参数和结果数据类型 使用PL/pgSQL所写的函数能够接受服务器支持的任何标量或数组数据类型作为参数, 并且同样能够返回这些类型的结果, 它们还可以接受或者返回任意用名字声明的复合类型(行类型)。 还可以将一个PL/pgSQL函数声明为一个返回`record`类型(行类型), 表明该结果是一个行类型,这个行的字段是在调用它的查询中指定的, 就像在[Section 7.2.1.4](#calibre_link-1746)里讨论的那样。 与声明SQL函数一样,通过使用`VARIADIC`可以对PL/pgSQL 进行声明为能接受可变数目的参数。 正如在[Section 35.4.5](#calibre_link-914)中讨论的那样。 PL/pgSQL函数还可以声明为接受并返回多态的 `anyelement`, `anyarray`, `anynonarray`, `anyenum`和`anyrange`类型。 一个多态函数实际操作的数据类型可以在不同的调用环境中变化, 如在[Section 35.2.5](#calibre_link-909)里讨论的那样。 [Section 40.3.1](#calibre_link-1667)是一个使用例子。 PL/pgSQL还可以声明为任何一个单个实例返回的数据类型"set",或者表。 这样的函数通过为结果集每个需要返回的元素执行一个`RETURN NEXT`生成它的输出, 或者通过使用`RETURN QUERY`来输出评估查询的结果。 最后,如果返回的结果没有太大的价值,PL/pgSQL函数可以声明为返回`void`。 PL/pgSQL函数也可以声明为输出某种类型的参数, 来代替明确的返回类型声明。 这么做并未给该语言增加任何基础设施, 只是通常更方便些,特别是返回多行数值的时候。同时, 也可以用`RETURNS TABLE`来代替`RETURNS SETOF`。 具体的例子在[Section 40.3.1](#calibre_link-1667)和 [Section 40.6.1](#calibre_link-1674)中。