如何在PostgreSQL中返回两个结果集?新手函数创建遇问题
解决PostgreSQL函数返回多个结果集的问题
嘿,刚接触PostgreSQL函数确实容易在返回多个结果集这里卡壳——我来帮你搞定这个问题!
首先看你写的代码,核心思路是对的,但有几个细节没处理好,导致函数没法正常返回你想要的结果。咱们一步步来修正:
1. 修正函数代码
首先,DECLARE只需要写一次,不用重复声明;另外,给游标指定明确的名称会让后续调用更清晰。修改后的函数如下:
CREATE OR REPLACE FUNCTION getData() RETURNS setof refcursor AS $$ DECLARE c_top_items refcursor; c_shopping_cart refcursor; BEGIN -- 打开第一个游标,指定名称方便后续调用 OPEN c_top_items FOR SELECT t.name FROM employee t LIMIT 10; RETURN NEXT c_top_items; -- 打开第二个游标 OPEN c_shopping_cart FOR SELECT c.name FROM employee c LIMIT 5; RETURN NEXT c_shopping_cart; END; $$ LANGUAGE plpgsql;
或者你也可以直接在OPEN时指定字符串形式的游标名,这样返回时更直观:
CREATE OR REPLACE FUNCTION getData() RETURNS setof refcursor AS $$ BEGIN OPEN 'top_items' FOR SELECT t.name FROM employee t LIMIT 10; RETURN NEXT 'top_items'::refcursor; OPEN 'shopping_cart' FOR SELECT c.name FROM employee c LIMIT 5; RETURN NEXT 'shopping_cart'::refcursor; END; $$ LANGUAGE plpgsql;
2. 正确调用函数的方式
这里最关键的一点:返回refcursor的函数必须在事务上下文中调用,而且调用后需要显式从游标中提取数据——直接调用函数只会返回游标对象,不会自动输出结果集。
比如用第一种函数的调用步骤:
-- 开启事务 BEGIN; -- 调用函数,获取游标引用 SELECT * FROM getData(); -- 从第一个游标中取出所有数据 FETCH ALL IN "<unnamed portal 1>"; -- 从第二个游标中取出所有数据 FETCH ALL IN "<unnamed portal 2>"; -- 提交事务 COMMIT;
如果用了指定名称的游标,调用会更清晰:
BEGIN; SELECT * FROM getData(); -- 直接用指定的游标名获取数据 FETCH ALL IN top_items; FETCH ALL IN shopping_cart; COMMIT;
为什么你的原函数不工作?
- 你可能没有在事务中调用函数,游标在非事务环境下会自动关闭,没法获取数据
- 调用函数后没有执行
FETCH语句,所以看不到实际的结果集 - 虽然重复写
DECLARE在语法上不会报错,但不符合PL/pgSQL的规范,容易引起混淆
这样调整后,你就能成功获取两个结果集啦!
内容的提问来源于stack exchange,提问作者Nayeem Mansoori
相关产品推荐
相关产品推荐

