方法一(不推荐使用):
这个写法会报错的:cursor already in use 。
原因:
当递归函数中定义游标时,需定义为非绑定游标,否则会产生错误:cursor already in use。
DECLARE
cur_films CURSOR FOR SELECT * FROM film;
cur_films2 CURSOR (year integer) FOR SELECT * FROM film WHERE release_year = year;
以上在定义里写好了sql语句的就是绑定游标。
绑定游标变量被初始化为字符串值表示其名称(官方文档成为portal name),后续一致不变。但非绑定游标变量初始缺省为null值,所以后期会接受一个自动生成的唯一名称。
参考:https://blog.csdn.net/neweastsun/article/details/90645200
CREATE OR REPLACE FUNCTION "score"."fun_score_level"("getscore" float8, "scoresumid" varchar)
RETURNS "pg_catalog"."varchar" AS $BODY$
declare --定义变量及游标
unbound_refcursor refcursor; --游标
v_levelscore float8;
v_levelname varchar(50);
v_overflow varchar(50);
v_levelrate float8;
bound_cursor cursor(scoresumid varchar(50)) for select levelscore,levelname,levelrate,overflow from score.sc_level where fk_scoresum = scoresumid order by levelscore desc;
begin --函数开始
open bound_cursor(scoresumid); --打开游标 并注入要搜索的字段的记录
loop --开始循环
fetch bound_cursor into v_levelscore,v_levelname,v_levelrate,v_overflow; --将游标指定的值赋值给变量
if found then --任意的逻辑
if v_overflow = 'Y' and getscore >= v_levelscore then
return v_levelname;
ELSEIF v_overflow = 'N' and getscore > v_levelscore then
return v_levelname;
end if;
else
exit;
end if;
end loop; --结束循环
close bound_cursor; --关闭游标
raise notice 'the end of msg...'; --打印消息
return 'D'; --为函数返回一个游标
exception when others then --抛出异常
raise exception 'error-----(%)',sqlerrm;--字符“%”是后面要显示的数据的占位符
end; --结束
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
方法二:
这个写法不报错了。
CREATE OR REPLACE FUNCTION fun_score_level(getscore float8,scoresumid varchar(50))
RETURNS varchar(50) AS --返回一个游标
$BODY$
declare --定义变量及游标
unbound_refcursor refcursor; --游标
v_levelscore float8;
v_levelname varchar(50);
v_overflow varchar(50);
v_levelrate float8;
begin --函数开始
open unbound_refcursor for select levelscore,levelname,levelrate,overflow from score.sc_level where fk_scoresum = scoresumid order by levelscore desc;
loop --开始循环
fetch unbound_refcursor into v_levelscore,v_levelname,v_levelrate,v_overflow; --将游标指定的值赋值给变量
if found then --任意的逻辑
if v_overflow = 'Y' and getscore >= v_levelscore then
return v_levelname;
ELSEIF v_overflow = 'N' and getscore > v_levelscore then
return v_levelname;
end if;
else
exit;
end if;
end loop; --结束循环
close unbound_refcursor; --关闭游标
raise notice 'the end of msg...'; --打印消息
return 'D'; --为函数返回一个游标
exception when others then --抛出异常
raise exception 'error-----(%)',sqlerrm;--字符“%”是后面要显示的数据的占位符
end; --结束
$BODY$
LANGUAGE plpgsql; --规定语言
参考:
https://blog.csdn.net/victor_ww/article/details/44240063
这两个写的比较简单易懂
https://www.cnblogs.com/102442/p/8409589.html
https://www.cnblogs.com/kerwincui/p/9122108.html