MySQL存储过程LOOP循环嵌套的使用说明

本篇代码都是自己编写运行通过的。

实现类似代码中
for(;;){}功能
这种结构会无限循环,所以需要结束标识leave来终止循环。
loop_1是随便写的,标识一下就可以,用来在leave生效时,确定中断那个loop

DELIMITER //
create procedure loop_test1()
begin
declare i int default 0;
loop_1: loop
    select i from dual;
    set i=i+1;
    if i>=5 then
        leave loop_1;//内部中断
    end if;
end loop;
end //

实现类似代码中foreach()/for in/for(inti=0;i<xxx.size();i++)等等
这类循环的量受外部循环量影响,循环次数有限。

leave同样可以用来中断循环。
LOOP结合cursor使用
DELIMITER //用来声明结束,因为默认状态下,分号;可能会导致存储过程提前结束
``DROP PROCEDURE IF EXISTSloop_test2““; #这句话在你反复修改存储过程时,很是必要的

CREATE  PROCEDURE loop_test2()
BEGIN
    DECLARE aid VARCHAR(36);    
    -- 遍历数据结束标志
    DECLARE done INT DEFAULT FALSE;
    DECLARE rep CURSOR FOR SELECT id FROM test_table;
    --NOT FOUND和 SQLSTATE '02000'是等价的
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN rep;
        loop_1:LOOP
            --如果游标查出来是多个值,fetch就可以into给多个变量
            FETCH rep INTO aid;
            IF done THEN #详细看下面解释
                LEAVE loop_1;
            END IF;
            SELECT * FROM test_table WHERE id=aid;
        END LOOP;
    CLOSE rep;
END //

我的test_table只有id和name两列数据。

为什么我上面那几句话要带删除线?因为那是我错误的理解。
上面的loop循环是没问题的,但是当我删除掉

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
这一句代码和相关if以后,编译通过,但是调用的时候总是0数据,其实是有的;

然后我就加上done的定义,但是去掉if判断,依旧是无线循环的调用……
也就是说,这个done的定义和判断,是必要的,自身应该是不存在有限次这一说的。

切记,不要拿自以为是的代码写博客,会害了很多人的。切记切记!


LOOP循环嵌套
测试数据:
table_a:

id
1
2

table_b:

numbenglish
1one
2two
DELIMITER //
DROP PROCEDURE IF EXISTS `testp`;
CREATE  PROCEDURE testp()
BEGIN
    DECLARE aid VARCHAR(36);
    DECLARE beng VARCHAR(36);   
    -- 遍历数据结束标志,两层循环用同一个标志,需要特别主意
    DECLARE done INT DEFAULT FALSE;
    DECLARE cura CURSOR FOR SELECT id FROM table_a;
    DECLARE curb CURSOR FOR SELECT english FROM table_b WHERE numb=aid;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN cura;
        a_loop:LOOP
            FETCH cura INTO aid;
            IF done THEN
                LEAVE a_loop;
            END IF;

            OPEN curb;
                b_loop:LOOP
                    FETCH curb INTO beng;
                    IF done THEN
                        LEAVE b_loop;
                    END IF;
                    SELECT * FROM table_b where english=beng;

                END LOOP;
            CLOSE curb;
            SET done=FALSE; #这个很重要
        END LOOP;
    CLOSE cura;
END //

注意::::::如果第二层循环中并列两个甚至多个循环,那么done这个标记就需要在每次二层循环结束的时候置为false;

切记,不要拿自以为是的代码写博客,会害了很多人的。切记切记!

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

公贵买其鹿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值