mysql使用游标cursor时循环额外多出一次的解决办法

mysql cursor 中使用循环(loop, 或者 repeat)时,循环每次会多执行一次。比如说,一次查询返回5条记录,使用cursor遍历时,循环会执行6次,当返回10条记录时,循环会遍历11次。出现这个现象的原因是,循环中的代码逻辑有点问题,稍加修改就能正常工作了。
先贴出有问题的代码:

DELIMITER //
CREATE PROCEDURE traverse_tables()
BEGIN
    DECLARE tabnames_smsi varchar(50);
    DECLARE smsi_done BOOLEAN DEFAULT 0;
    DECLARE source_table_smsi CURSOR FOR SELECT DISTINCT smsi  FROM module_name;    
    -- 定义循环结束条件
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET smsi_done = 1;    
    -- 打开游标
    OPEN source_table_smsi;    
    smsi_loop: REPEAT
        FETCH source_table_smsi INTO tabnames_smsi;
        select tabnames_smsi, smsi_done;  
    UNTIL smsi_done END REPEAT smsi_loop;    
    -- 关闭游标
    CLOSE source_table_smsi;
END//
DELIMITER ;

当没有新的记录可供遍历时,SQLSATTE '02000'会出现,这时smsi_done变量会被置为1,此时还会再多执行select tabnames_smsi, smsi_done;一次,导致一个多余的循环。因此,需要首先在循环体中检查smsi_done这个变量的值,当为1时,跳出循环,不为1时才执行循环体。

改进后的代码:

DELIMITER //
CREATE PROCEDURE traverse_tables()
BEGIN
    DECLARE tabnames_smsi varchar(50);
    DECLARE smsi_done BOOLEAN DEFAULT 0;
    DECLARE source_table_smsi CURSOR FOR SELECT DISTINCT smsi  FROM module_name;    
    -- 定义循环结束条件
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET smsi_done = 1;    
    -- 打开游标
    OPEN source_table_smsi;    
    smsi_loop: REPEAT
        FETCH source_table_smsi INTO tabnames_smsi;
        IF NOT smsi_done THEN
            select tabnames_smsi, smsi_done;  
        END IF;
    UNTIL smsi_done END REPEAT smsi_loop;    
    -- 关闭游标
    CLOSE source_table_smsi;
END//
DELIMITER ;


或者也可以这样写

DELIMITER //
CREATE PROCEDURE traverse_tables()
BEGIN
    DECLARE tabnames_smsi varchar(50);
    DECLARE smsi_done BOOLEAN DEFAULT 0;
    DECLARE source_table_smsi CURSOR FOR SELECT DISTINCT smsi  FROM module_name;    
    -- 定义循环结束条件
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET smsi_done = 1;    
    -- 打开游标
    OPEN source_table_smsi;    
    smsi_loop: REPEAT
        FETCH source_table_smsi INTO tabnames_smsi;
        IF smsi_done THEN
            -- 关闭游标
            CLOSE source_table_smsi;
            -- 跳出循环
            LEAVE smsi_loop;
        END IF;
        select tabnames_smsi, smsi_done;  
    UNTIL smsi_done END REPEAT smsi_loop; 
END//
DELIMITER ;

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值