↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本PostgreSQL 7.2 已于 2007 年 2 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

第 23 章 PL/pgSQL - SQL 过程语言

PL/pgSQL是PostgreSQL 数据库系统的一个可装载过程语言。

这个软件包最初由 Jan Wieck 编写。本文档的一部分由 Roberto Mello()撰写。

23.1. 概述 #

PL/pgSQL的设计目标是创建一种可装载的过程 语言,它

  • 可以用来创建函数和触发器过程,

  • 向SQL语言中增加控制结构,

  • 能执行复杂的计算,

  • 继承所有用户定义的类型、函数和操作符,

  • 可以被定义为服务器所信任,

  • 易于使用。

PL/pgSQL调用处理器在函数第一次被调用时(在任一后端 进程内)解析函数的源文本并生成一棵内部二进制指令树。指令树 完整地翻译了PL/pgSQL的语句结构,但函数中 使用的各个SQL表达式和SQL 查询并不会立即被翻译。

当函数中的每个表达式和SQL查询第一次被使用时, PL/pgSQL解释器会创建一个预备好的执行计划 (使用SPI管理器的SPI_prepare 和SPI_saveplan函数)。之后再遇到该表达式 或查询时会重用这个预备好的计划。因此,一个包含大量可能需要 执行计划的条件语句的函数,只会准备和保存那些在数据库连接 生命期内真正被用到的计划。这可以节省大量的解析活动。一个 缺点是某个特定表达式或查询中的错误可能直到执行到函数的 那一部分时才会被发现。

一旦PL/pgSQL为函数中的某个特定查询生成了查询计划, 它就会在数据库连接的整个生命期内重用该计划。这通常对性能 有利,但如果你动态地更改数据库模式,它也可能引起一些问题。 例如:

CREATE FUNCTION populate() RETURNS INTEGER AS '
DECLARE
    -- Declarations
BEGIN
    PERFORM my_function();
END;
' LANGUAGE 'plpgsql';

如果你执行上面的函数,它会为 PERFORM 语句生成的查询计划引用 my_function()的 OID。之后如果你删除并 重建my_function(),那么 populate()将再也无法找到 my_function()。此时你必须重建 populate(),或者至少启动一个新的数据库 会话让它重新编译。

由于PL/pgSQL以这种方式保存执行计划,直接 出现在PL/pgSQL函数中的查询在每次执行时必须 引用相同的表和字段;也就是说,你不能在查询中把参数用作表名或 字段名。要绕开这一限制,你可以使用PL/pgSQL 的 EXECUTE 语句构造动态查询——代价是每次执行都要构造一个新的 查询计划。

除了用户定义类型的输入/输出转换和计算函数之外,凡是能用 C 语言 函数定义的东西也都可以用PL/pgSQL完成。 你可以创建复杂条件计算函数,之后用它们来定义操作符,或在 函数索引中使用它们。

23.1.1. 使用 PL/pgSQL 的优势 #

23.1.1.1. 更好的性能 #

SQL是PostgreSQL(以及大多数其他 关系数据库)用作查询语言的语言。它可移植且易于学习。但每条 SQL语句都必须由数据库服务器逐条执行。

这意味着你的客户端应用必须把每个查询发送到数据库服务器, 等待它处理,接收结果,做一些计算,然后再把其他查询发送给 服务器。所有这些都会带来进程间通信开销,而且如果你的客户端 与数据库服务器不在同一台机器上,还会带来网络开销。

使用PL/pgSQL,你可以把一块计算和一系列查询 封装在数据库服务器内部,从而既拥有过程语言 的能力又拥有 SQL 的易用性,同时因为省去了整个客户端/服务器 通信开销而节省大量时间。这可以带来相当可观的性能提升。

23.1.1.2. SQL 支持 #

PL/pgSQL把过程语言的能力加到了 SQL的灵活和易用之上。使用 PL/pgSQL,你可以使用 SQL 的所有数据类型、 列、操作符和函数。

23.1.1.3. 可移植性 #

由于PL/pgSQL函数运行在PostgreSQL 内部,这些函数可以在PostgreSQL运行的任何平台上 运行。因此你可以重用代码并降低开发成本。

23.1.2. 用PL/pgSQL开发 #

用PL/pgSQL开发相当直接,尤其是如果你曾经用 其他数据库过程语言(例如 Oracle 的PL/SQL) 开发过。用PL/pgSQL开发的两个好办法是:

  • 使用文本编辑器并用psql重新装载文件

  • 使用PostgreSQL的 GUI 工具:PgAccess

用PL/pgSQL开发的一个好办法就是用你喜欢的文本 编辑器创建函数,然后在另一个控制台用psql (PostgreSQL 的交互监视器)装载这些函数。如果你采用这种 方式,一个好主意是用CREATE OR REPLACE FUNCTION编写函数。这样你就可以重新装载文件来更新 函数定义。例如:

CREATE OR REPLACE FUNCTION testfunc(INTEGER) RETURNS INTEGER AS '
    ....
end;
' LANGUAGE 'plpgsql';

在psql运行期间,你可以用下面的命令装载或 重新装载这样一个函数定义文件:

    \i filename.sql

然后立即发出 SQL 命令来测试该函数。

用PL/pgSQL开发的另一个好办法是使用 PostgreSQL的 GUI 工具PgAccess。它会 替你做一些好事,比如转义单引号,并且让重建和调试函数变得 容易。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。