您的位置:寻梦网首页编程乐园数据库PostgreSQL 7.2 Documentation

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 一个绑定的查询

OPEN 

bound-cursor

 [
 ( 

argument_values

 ) 
];

这种形式的 OPEN 用于打开一个游标变量,该游标变量的查询是在声明 的时候和它绑定在一起的.游标不能是已经打开的. 当且仅当该游标声明为接受参数的时候,语句中才必需出现一个实际 参数值表达式的列表.这些值将代换到查询中. 一个绑定的游标的查询计划总是认为可缓冲的 -- 这种情况下 没有等效的 EXECUTE.

OPEN curs2;
OPEN curs3(42);

23.7.3. 使用游标

一旦你已经打开了一个游标,那么你就可以用这里描述的语句操作它.

这些操作不需要发生在和打开该游标开始操作的同一个函数里. 你可以从函数里返回一个 refcursor 数值,然后让 调用者操作该游标.(在内部, refcursor 值只是一个 包含用于该游标查询的信使的字串名.这个名字可以传来传去, 可以赋予其它 refcursor 变量等等,也不用担心扰乱信使.)

所有信使在事务的结尾都会隐含地关闭.因此一个 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 关闭支撑在一个打开的游标下面的信使. 这样我们就可以在事务结束之前施放资源,或者释放掉该游标变量, 用于稍后再次打开.

CLOSE curs1;