PostgreSQL调用双游标返回存储过程时FETCH ALL无数据问题
问题根因
测试代码无法获取游标数据,核心是存在以下用法错误:
DO匿名块默认不会向客户端返回查询结果,你用EXECUTE执行FETCH ALL时没有指定数据接收目标,取到的数据会被直接丢弃,不会有任何展示- refcursor是事务级会话游标,匿名块执行结束后事务会自动提交,游标会被直接销毁
- 代码中的
RAISE NOTICE仅打印了ca_cur变量本身存储的游标名称字符串,根本没有输出游标里存储的实际行数据 - 多余定义的
counter refcursor := 0无实际作用,refcursor类型用于存储游标名称,赋值数值0没有意义
可直接运行的正确测试方案
方案1:匿名块内读取数据并打印日志
适合直接在运行日志里查看游标返回内容,不需要返回结果到查询窗口:
DO $$ DECLARE ca_cur refcursor; tx_cur refcursor; row_data record; BEGIN -- 调用存储过程接收两个输出游标 CALL dbo.show_cities_multiple2(ca_cur, tx_cur); -- 先校验游标是否正常生成 RAISE NOTICE '生成的游标:ca_cur=%, tx_cur=%', ca_cur, tx_cur; -- 遍历读取tx_cur所有数据 RAISE NOTICE '===== tx_cur 返回数据 ====='; LOOP FETCH NEXT FROM tx_cur INTO row_data; EXIT WHEN NOT FOUND; RAISE NOTICE '%', row_data; END LOOP; -- 遍历读取ca_cur所有数据 RAISE NOTICE '===== ca_cur 返回数据 ====='; LOOP FETCH NEXT FROM ca_cur INTO row_data; EXIT WHEN NOT FOUND; RAISE NOTICE '%', row_data; END LOOP; END $$;
方案2:直接返回游标结果到查询窗口
如果需要像普通SELECT一样把结果返回到客户端结果面板,不要用DO块,手动控制事务调用即可:
-- 开启事务 BEGIN; -- 调用存储过程,指定游标名称方便引用 CALL dbo.show_cities_multiple2('ca_cur', 'tx_cur'); -- 直接拉取游标所有数据,结果会直接展示在结果面板 FETCH ALL FROM ca_cur; FETCH ALL FROM tx_cur; -- 提交事务关闭游标 COMMIT;
额外注意点
如果执行时提示游标不存在,先检查存储过程dbo.show_cities_multiple2的内部逻辑,确认两个OUT类型的refcursor参数被正确绑定到OPEN打开的游标上,没有出现参数赋值遗漏的情况
内容的提问来源于stack exchange,提问作者Ahmed AbuBakar
相关产品推荐
相关产品推荐

