oracle_游标_最后一个会重复取一次的问题

oracle和mysql的游标都有这个相同的问题,以Oracle说明,同样适用于mysql;

问题:

游标循环的最后一个会重复循环一次,错误如下:

现象:

【exit when 游标名称%not found】放置的位置不同会有不同的效果;

若放置在loop循环的末尾进行判断,则会导致重复;

若放置在loop循环的fetch取值之后,执行结构之前,就是正常的,不会重复;

想想为啥!?

分析:

游标循环判断的逻辑是对本次fetch进行数据有无的判断,而不是移动到下一个记性判断。

所以,本来最后一次后应退出结束循环,实际并没有,因为exit when 游标名称%not found判断的是本次fetch有没有数据,当然是有的,30呀,那么就会继续loop循环,下一次的循环赋值时fetch就没取到,那变量就没有被刷新赋值,所以保持着最后一次的变量值进行循环执行了语句,再到了最后的判断结构【exit when 游标名称%not found】判断时,此次的fetch是没有数据,就符合退出条件,所以就会结束循环,所以会导致游标的最后一行数据被重复循环一次。

本质:

不同放置位置的本质为:

【先判断后执行】 / 【先执行后判断】

解决:

按照 【先判断后执行】 去设置 【exit when 游标名称%not found】的放置位置

既然exit是判断的当次的fetch有无数据,那么就先判断后执行,将判断结构放在具体的执行语句之前,保证当次fetch有数据才执行,不会重复;

CREATE OR REPLACE PROCEDURE SP_VSQL_CURSOR 
AS
  CURSOR CUR_DNO IS SELECT DEPTNO FROM DNO;   -- DNO中仅一个字段,有10/20/30共3个数据
  V_DNO NUMBER;
BEGIN
  OPEN CUR_DNO;
  
  LOOP
    FETCH CUR_DNO INTO V_DNO;     
    
    EXIT WHEN CUR_DNO%NOTFOUND;     -- 此时,为【先判断后执行】
    
    INSERT INTO EMP_INSERT SELECT * FROM EMP WHERE DEPTNO=V_DNO;  
     
  END LOOP;
  
  CLOSE CUR_DNO;
END;
/

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值