• mysql 游标 loop while 的使用


    项目需求:对表进行重新构建,这个用java的缺点是数据的传送以及遍历的话会消耗更多的资源,因此使用mysql的存储过程进行构建。

    具体要求:跳过原本设置的假期和课程本身的假期对数据进行重排。

    1.游标从创建到关闭的过程: 注意class_id1 的属性刚开始由declare设置的默认是空,但在打开游标之前只要给它重新赋值就不为空了。

    DECLARE cc_2 CURSOR FOR SELECT id FROM pms_teach_example_day where class_id=class_id1 AND id>=(SELECT id FROM pms_teach_example_day WHERE class_id=class_id1 AND date is NULL ORDER BY id limit 1);

    2.定义结束条件:02000是sql的状态码,意思是这条sql语句执行到最后了,当然在最开始的时候要定义done这个属性,默认值设为0,如果这个done属性还用在其他游标里,每次关闭游标前把done设置为0(重点),以下是定义结束条件的两种写法。

    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;

    3.打开游标进行循环:循环也可以有两种:一种就是repeat 另一种就是loop,loop的好处是可以控制循环何时跳出,记得打开loop要跟着跳出loop和关闭loop的结束语句,另外,在这里边虽然没有写done 的值但是它默认结束后就会给你返回1,因此在关闭游标前依旧要把done的值设为0,这个很坑,因为mysql的变量都是全局变量,一处修改下次就不能用了,所以一定要重置,cc_2可以简单理解为查询的每一行。

    写法一:

    OPEN cc_2;
    tloop:LOOP
    FETCH cc_2 INTO id2;
    SET date2 = (SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(date3,',',j+1),',',-1));
    IF i>j THEN
    update pms_teach_example_day SET date = date2 WHERE id = id2 ;
    SET j=j+1;
    END IF;
    IF i=j THEN
    LEAVE tloop;
    END if;
    END LOOP tloop;
    SET j =0;
    SET done =0;
    CLOSE cc_2;

    写法二:

    OPEN t_index;
    REPEAT
    FETCH cc_2 INTO id2;
    IF done!=1 THEN
    //操作语句
    END IF;
    UNTIL DONE END REPEAT;
    CLOSE t_index;

    5.嵌套循环:嵌套循环最好用游标嵌套,然后两个loop之类的,这里为了方便用了while-游标嵌套,b:BEGIN是写了一个外部的标签,因为我要循环365次,但是总不会真的要循环这么多次,当条件满足后就可以通过这个标签来进行跳出循环,跳出的语句跟loop一样:LEAVE b; 嵌套循环实现跟java一样,外部执行一次,里边要完整的循环一次,注意END LOOP 之后这个内循环就已经关闭了,END LOOP 和CLOSE cc_2之间已经不算在循环里了,所以说标红的之一段代码是外循环里的,我的外循环是用jj来进行控制,内循环的话就是自然执行完,特别注意  j  这个属性,这个属性在内循环中一直使用,因此每次外循环调用的时候要重新给它赋值,这样的话才能保证每次内循环  j   开始的值是固定的。

    6.最后最后,一定要开始事务,将需要保持原子性的代码都放在一个事务里,不然你有的执行成功有的执行不成功会造成数据混乱。

    6.控制循环次数时,不要用内置函数,length,replace来控制,非常消耗性能。

    7.注意,当没有set的时候变量不会自己赋值,即declare 一个int 的变量时一定要初始化为0,这样才能进入循环;

    8.坑:done!=1和done=1,先看两个截图:

    因为第二张图的if后边没加结束的条件,所以循环到最后之后还是把i加1了,注意这个加一操作是在循环结束后加的,然后判断done=1再跳出的时候就会发现i比正常的值多1。

    9.代码整理(没加事务):

    我不是程序员,我只是程序的搬运工
  • 相关阅读:
    labview 中的一些简写全称
    socket
    putty
    在波形图表中显示多条曲线
    简单的通电延时触发电路
    Linux sed 批量替换多个文件中的字符串
    PhpMyAdmin管理,登录多台远程MySQL服务器
    MySQL客户端工具推荐
    Redis的几个认识误区
    Redis 的 5 个常见使用场景
  • 原文地址:https://www.cnblogs.com/keith0/p/12788468.html
Copyright © 2020-2023  润新知