我有一个返回setof游标的程序
现在我必须将该过程调用到另一个过程并访问数据
通过该程序返回
他们是什么方式在postgres做到这一点。
这是第一个程序的代码,
CREATE OR REPLACE FUNCTION public.returns_multiple_cursor( )
RETURNS SETOF refcursor
LANGUAGE 'plpgsql'
COST 100.0
AS $function$
DECLARE
_daily refcursor := 'first_cur';
_fac_hourly refcursor := 'second_cur';
BEGIN
open first_cur for
select * from x;
return next first_cur;
open second_cur for
select * from y;
return second_cur;
END
$function$;
ALTER FUNCTION public.returns_multiple_cursor();
这里是其他第二个程序的代码
CREATE OR REPLACE FUNCTION public.access_cursor( )
RETURNS SETOF refcursor
LANGUAGE 'plpgsql'
COST 100.0
AS $function$
DECLARE
BEGIN
-- what code will be here to access the cursor data in this procedure
select public.returns_multiple_cursor();
END;
ALTER FUNCTION public.access_cursor();
答案 0 :(得分:0)
不幸的是,你不能使用FOR <recordvar> IN <cursor>
循环,因为它只适用于绑定游标(refcursor
不是)。
但你仍然可以使用老式的FETCH
:
declare
rec record;
cur refcursor;
begin
for cur in select returns_multiple_cursor() loop
loop
fetch next from cur into rec;
exit when not found;
-- do whatever you want with the single rows here
end loop;
close cur;
end loop;
end
不幸的是,还有另一个限制:PostgreSQL缓存了第一个游标的计划(至少,似乎它做了类似的事情),所以你必须使用游标,它使用相同的列类型(你&#39 ; ll必须使用相同的列名,以便能够在内循环中引用它们,如rec.col1
)。
完整的,有效的示例:http://rextester.com/FNWG91106(请参阅f.ex.当您从游标&#39;查询中删除投射时会发生什么。)
如果你有固定游标数量(如你的例子),但结构不同的底层查询,可能更容易将returns_multiple_cursor
声明为:
create or replace function returns_multiple_cursor(out first_cur refcursor,
out second_cur refcursor)
-- returns record (optional)
language plpgsql
-- ...
这样,您可以在调用上下文中更直接地访问游标。
更新:似乎当您不使用显式列名称,只是通用记录处理(通过f.ex.JSON或hstore
)时,计划缓存不会造成任何麻烦: