我声明、打开并获取了一个游标。在一个循环中,如果我检查 pg_cursors 中的计数,我只会得到 0。在以前的版本 PostgreSQL 11 中,它工作正常。但是,我只在 PostgreSQL 16 中遇到这个问题。
示例代码如下,即使光标保持值,也会打印“我没有进入循环”:
CREATE OR REPLACE PROCEDURE gis_in.pg_cur_test1()
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
rec record;
m_cnt int;
pg_cur CURSOR FOR SELECT id
FROM emp;
m_bref numeric;
BEGIN
open pg_cur;
fetch pg_cur into m_bref;
if exists(select 1 from pg_cursors where name = 'pg_cur') then
loop
exit when not found;
raise info 'm_bref is :,%',m_bref;
fetch pg_cur into m_bref;
end loop;
end if;
raise info 'I did not get inside the loop';
close pg_cur;
END;
$BODY$;
PostgreSQL 16 使用唯一的游标名称(默认情况下),例如
<unnamed portal 3>
,...,但您可以通过将名称分配给游标变量来强制使用名称:
CREATE OR REPLACE PROCEDURE gis_in.pg_cur_test1()
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
rec record;
m_cnt int;
pg_cur CURSOR FOR SELECT id
FROM emp;
m_bref numeric;
BEGIN
-- set custom name for cursor
pg_cur := 'pg_cur';
open pg_cur;
fetch pg_cur into m_bref;
if exists(select 1 from pg_cursors where name = 'pg_cur') then
loop
exit when not found;
raise info 'm_bref is :,%',m_bref;
fetch pg_cur into m_bref;
end loop;
end if;
raise info 'I did not get inside the loop';
close pg_cur;
END;
$BODY$;
我个人不太明白用法
IF EXISTS(SELECT ... FROM pg_cursors) WHERE name = 'pg_curs') THEN
。如果 open
语句没有失败,则始终为真(对于任何 PostgreSQL 版本)。也许你想写一些像:
CREATE OR REPLACE PROCEDURE gis_in.pg_cur_test1()
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
rec record;
m_cnt int;
pg_cur CURSOR FOR SELECT id
FROM emp;
m_bref numeric;
BEGIN
if not exists(select 1 from pg_cursors where name = 'pg_cur') then
pg_cur := 'pg_cur';
open pg_cur;
end if;
fetch pg_cur into m_bref;
loop
exit when not found;
raise info 'm_bref is :,%',m_bref;
fetch pg_cur into m_bref;
end loop;
end if;
raise info 'I did not get inside the loop';
close pg_cur;
END;
$BODY$;