您将SQL 游标与PL/pgSQL 游标混淆了,它们相似但不相同。特别是FETCH FORWARD
count
plpgsql中没有:
方向子句可以是 SQLFETCH
命令中允许的任何变体,除了可以获取多行的变体;即,它可以是NEXT
, PRIOR
, FIRST
, LAST
, ABSOLUTE
count, RELATIVE
count, FORWARD
, 或BACKWARD
.
在 plgpsql 中,您一次只能获取一行并处理(或返回)它。手册中还有免责声明:
注意:本页描述了 SQL 命令级别的游标的使用。如果您尝试在 PL/pgSQL 函数中使用游标,则规则是不同的。
您可以在 plpgsql 中打开该游标并循环返回 rows。但这仅在您想从大光标中获取多个不同的部分以节省开销时才相关。否则一个普通的FOR
循环(带有自动光标)或一个简单SELECT
的 with OFFSET
andLIMIT
肯定会更快。游标主要是为了返回给客户端并由客户端使用:
CREATE OR REPLACE FUNCTION getbatch_ref(_cursor refcursor, _workload_id text)
RETURNS refcursor AS
$func$
BEGIN
OPEN $1 SCROLL FOR
SELECT id
FROM workload
WHERE workload_id = $2
ORDER BY id;
RETURN $1;
END
$func$ LANGUAGE plpgsql;
您可以在 SQL 中使用此函数:
BEGIN;
SELECT getbatch_ref('c', 'foo');
MOVE FORWARD 10 IN c;
FETCH FORWARD 10 FROM c;
ROLLBACK; -- or COMMIT;
你也可以只使用普通的 SQL:
BEGIN;
DECLARE c SCROLL CURSOR FOR
SELECT id
FROM workload
WHERE workload_id = 'foo'
ORDER BY id;
-- OPEN c; -- only relevant in plpgsql
-- The PostgreSQL server does not implement an OPEN statement for cursors;
-- a cursor is considered to be open when it is declared.
MOVE FORWARD 10 IN c;
FETCH FORWARD 10 FROM c;
ROLLBACK; -- or COMMIT;