mysql 存储过程使用游标时 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE 会提前执行的坑...

我们在使用储存过程中使用游标遍历数据的时候的基本写法如下:

create procedure proc_test() sql security invoker
begin
  declare p_id varchar(32);
  declare done tinyint default false;
  declare c_cur cursor for select id from user;
  declare continue handler for not found set done = true;
  
  open c_cur;
    fetch c_cur into p_id;
    while !done do
    ... #程序逻辑
    fetch c_cur into p_id;
    end while;
  close c_cur;
end;

正常情况这么写是没问题的,可是如果你在while里面的要是有select语句的话就有问题了。如果说你的处理逻辑是这样的:

while !done do
  select * from user_role r where r.user_id = p_id;
  fetch c_cur into p_id; 
end while;

那么当你的select * from user_role r where r.user_id = p_id;找不到数据的时候,declare continue handler for not found set done = true;这句就会执行,有done = true,所以循环体会提前跳出。通过测试得出,declare continue handler for not found set done = true 是对全局的select有效的,只要有一条select语句返回空,那么就是触发该语句。

解决方法就是确保while里面的select永远不会返回空

select * from user_role r where r.user_id = p_id;

#改成下面这样
select col1, col2, ... from
(select col1, col2, ... from user_role r where r.user_id = p_id
union all
select '' col1, '' col2, ...) t

这样的话就可以保证select肯定不是空集合。

转载于:https://my.oschina.net/linchuhao23/blog/2252251

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值