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

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
历史版本PostgreSQL 7.2 已于 2007 年 2 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

23.7. 游标 #

与一次执行整个查询不同,可以先建立一个封装该查询的 游标,然后每次读取查询结果的若干行。 这样做的一个原因是避免结果包含大量行时的内存溢出。 (不过PL/pgSQL用户通常不需要担心这一点, 因为 FOR 循环会在内部自动使用游标来避免内存问题。)一个 更有趣的用法是函数可以返回一个指向它所建立的游标的引用, 让调用方去读取这些行。这提供了从函数返回行集的一种办法。

23.7.1. 声明游标变量 #

PL/pgSQL中对游标的所有访问都通过游标变量进行, 游标变量总是特殊数据类型refcursor。创建游标变量的一种 办法就是把它声明为refcursor类型的变量。另一种办法是 使用游标声明语法,其一般形式是:

name CURSOR [ ( arguments ) ] FOR select_query ;

(为了与 Oracle 兼容,FOR可以替换为 IS。)arguments (如果有)是一个由name datatype对组成的逗号分隔列表,这些 名字在给定查询中将被参数值替换。替换这些名字的实际值将在 稍后打开游标时指定。

一些例子:

DECLARE
    curs1 refcursor;
    curs2 CURSOR FOR SELECT * from tenk1;
    curs3 CURSOR (key int) IS SELECT * from tenk1 where unique1 = key;

这三个变量的数据类型都是refcursor,但第一个可以 与任何查询一起使用,第二个已经有一个完整指定的查询 绑定在它上面,而最后一个绑定了一个 参数化查询。(打开游标时key会被一个整数 参数值替换。)变量curs1被称为 未绑定的,因为它没有绑定到任何特定 的查询。

23.7.2. 打开游标 #

在游标可以用来检索行之前,它必须被打开。 (这等价于 SQL 命令DECLARE CURSOR。) PL/pgSQL有四种形式的 OPEN 语句,其中两种 用于未绑定的游标变量,另外两种用于绑定的游标变量。

23.7.2.1. OPEN FOR SELECT

OPEN unbound-cursor FOR SELECT ...;

游标变量被打开并被赋予要执行的指定查询。该游标不能已经 处于打开状态,而且它必须已被声明为未绑定游标(也就是一个 简单的refcursor变量)。SELECT 查询的处理方式 与PL/pgSQL中的其他 SELECT 相同:会替换 PL/pgSQL变量名,并且查询计划会被缓存以 便可能的重用。

OPEN curs1 FOR SELECT * FROM foo WHERE key = mykey;

23.7.2.2. OPEN FOR EXECUTE

OPEN unbound-cursor FOR EXECUTE query-string;

游标变量被打开并被赋予要执行的指定查询。该游标不能已经 处于打开状态,而且它必须已被声明为未绑定游标(也就是一个 简单的refcursor变量)。查询以与 EXECUTE 命令 相同的方式指定为字符串表达式。与通常一样,这让查询可以 在每次运行之间变化,提供了灵活性。

OPEN curs1 FOR EXECUTE ''SELECT * FROM '' || quote_ident($1);

23.7.2.3. 打开绑定的游标

OPEN bound-cursor [ ( argument_values ) ];

这种形式的 OPEN 用于打开其查询在声明时就已绑定到它上面的 游标变量。该游标不能已经处于打开状态。当且仅当游标被声明为 接受参数时,才必须出现一个实际参数值表达式的列表。这些值 会被替换进查询中。绑定游标的查询计划总被认为是可缓存的 ——这种情况下没有 EXECUTE 的等价物。

OPEN curs2;
OPEN curs3(42);

23.7.3. 使用游标 #

游标一旦被打开,就可以用这里描述的语句来操纵它。

这些操纵不必发生在最初打开游标的同一个函数中。你可以从函数 返回一个refcursor值,让调用方操作该游标。 (在内部,refcursor值只是包含该游标的活动查询的 Portal 的字符串名字。这个名字可以被传递、赋给其他 refcursor变量等等,而不会干扰 Portal。)

所有 Portal 都会在事务结束时被隐式关闭。因此 refcursor值只在事务结束之前引用打开的游标才有用。

23.7.3.1. FETCH

FETCH cursor INTO target;

FETCH 从游标中检索下一行放到目标中,目标可以是行变量、 记录变量或由简单变量组成的逗号分隔列表,与 SELECT INTO 相同。与 SELECT INTO 一样,可以检查特殊变量 FOUND 来看 是否取得了行。

FETCH curs1 INTO rowvar;
FETCH curs2 INTO foo,bar,baz;

23.7.3.2. CLOSE

CLOSE cursor;

CLOSE 关闭一个打开的游标底层的 Portal。这可以用来在事务 结束之前更早地释放资源,或者腾出游标变量以便再次打开它。

CLOSE curs1;

提交更正

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