postgres 版本 16 中的 PG_CURSORS 行为

问题描述 投票:0回答:1

我声明、打开并获取了一个游标。在一个循环中,如果我检查 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 plpgsql
1个回答
0
投票

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$;
© www.soinside.com 2019 - 2024. All rights reserved.