postgreSQL 游标使用

方法一(不推荐使用):

这个写法会报错的: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  

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值