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

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

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

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

你可能感兴趣的:(mysql 存储过程使用游标时 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE 会提前执行的坑...)