PL/pgSQL 函数可以向调用者返回游标。这个功能用于从函数里返回多行或多列,特别是巨大的结果集。要想这么做,该函数必须打开游标并且把该游标的名字返回给调用者,或者简单的使用指定的入口名或调用者已知的名字打开游标。调用者然后从游标里抓取行。游标可以由调用者关闭,或者是在事务结束的时候自动关闭。
函数返回的游标名可以由调用者声明或者自动生成。要声明一个信使的名字,只要在打开游标之前,给 refcursor 变量赋予一个字符串就可以了。refcursor 变量的字符串值将被 OPEN 当作下层的信使的名字使用。不过,如果 refcursor 变量是空,那么 OPEN 将自动生成一个和现有信使不冲突的名字,然后将它赋予 refcursor 变量。
【注意】 一个绑定的游标变量其名字初始化为对应的字符串值,因此信使的名字和游标变量名同名,除非程序员在打开游标之前通过赋值覆盖了这个名字。但是一个未绑定的游标变量初始化的时候缺省是空,因此它会收到一个自动生成的唯一名字,除非被覆盖。
下面的例子显示了一个调用者声明游标名字的方法:
CREATE TABLE test (col text);
INSERT INTO test VALUES ('123');
CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS '
BEGIN
OPEN $1 FOR SELECT col FROM test;
RETURN $1;
END;
' LANGUAGE plpgsql;
BEGIN;
SELECT reffunc('funccursor');
FETCH ALL IN funccursor;
COMMIT;
下面的例子使用了自动生成的游标名:
CREATE FUNCTION reffunc2() RETURNS refcursor AS '
DECLARE
ref refcursor;
BEGIN
OPEN ref FOR SELECT col FROM test;
RETURN ref;
END;
' LANGUAGE plpgsql;
BEGIN;
SELECT reffunc2();
reffunc2
--------------------
(1 row)
FETCH ALL IN "";
COMMIT;
下面的例子显示了从一个函数里返回多个游标的方法:
CREATE FUNCTION myfunc(refcursor,refcursor) RETURNS SETOF refcursor AS $$
BEGIN
OPEN $1 FOR SELECT * FROM table_1;
RETURN NEXT $1;
OPEN $2 FOR SELECT * FROM table_2;
RETURN NEXT $2;
END;
$$ LANGUAGE plpgsql;
-- 需要在事务里使用游标。
BEGIN;
SELECT * FROM myfunc('a','b');
FETCH ALL FROM a;
FETCH ALL FROM b;
COMMIT;