【问题标题】:MySQL Stored Procedure - Nested loop at fault?MySQL 存储过程 - 嵌套循环出错?
【发布时间】:2016-06-01 11:12:33
【问题描述】:

我在下面有一个中等大小的存储过程。我的问题是它什么也没做,我不知道为什么。

1.) 首先是代码:

    DROP PROCEDURE IF EXISTS deleteabundant_fixshared_shiftResources;
    DELIMITER //
    CREATE PROCEDURE deleteabundant_fixshared_shiftResources ()
    BEGIN
      DECLARE finish_flag BOOLEAN DEFAULT FALSE;
      DECLARE id INT(11);
      DECLARE startTime DATETIME;
      DECLARE endTime DATETIME;
      DECLARE shid INT(11);
      DECLARE resid INT(11);

      DECLARE id_inner INT(11);
      DECLARE startTime_inner DATETIME;
      DECLARE endTime_inner DATETIME;
      DECLARE shid_inner INT(11);
      DECLARE resid_inner INT(11);
      DECLARE cr130 CURSOR FOR SELECT shift_resource_id, start_date, end_date, shift_id, resource_id FROM temp_shift_resource;
      DECLARE cr131 CURSOR FOR SELECT shift_resource_id, start_date, end_date, shift_id, resource_id FROM temp_shift_resource;
        DECLARE CONTINUE HANDLER  FOR NOT FOUND SET finish_flag = TRUE; 

    START TRANSACTION;  



    OPEN cr130;
    OPEN cr131;
        OUTERLOOP: LOOP
        FETCH cr130 into id, startTime, endTime, shid, resid;
        IF finish_flag THEN LEAVE OUTERLOOP; END IF;
            INNERLOOP: LOOP
            FETCH cr131 INTO id_inner, startTime_inner, endTime_inner, shid_inner, resid_inner;
        IF finish_flag THEN LEAVE INNERLOOP; END IF;
        IF (id!=id_inner) THEN
        IF (resid=resid_inner AND shid_inner!=9) THEN

     -- logic to determine if the dates are wrong:
            IF (startTime<=startTime_inner AND endTime>=endTime_inner) THEN
                INSERT INTO repairchange ( shift_resource_id, changetype, shift_id, resource_id, start_date, end_date ) 
                                  VALUES ( id_inner, "FD", shid_inner, resid_inner, startTime_inner, endTime_inner );
                DELETE FROM temp_shift_resource WHERE shift_resource_id = id_inner;
            ELSEIF (endTime>=endTime_inner AND startTime<=endTime_inner) THEN
                INSERT INTO repairchange ( shift_resource_id, changetype, shift_id, resource_id, start_date, end_date ) 
                                  VALUES ( id_inner, "FU", shid_inner, resid_inner, startTime_inner, endTime_inner );
                UPDATE temp_shift_resource set endTime_inner=(startTime - INTERVAL 1 DAY) where shift_resource_id = id_inner;
            ELSEIF (startTime<=startTime_inner AND endTime>=startTime_inner) THEN
                INSERT INTO repairchange ( shift_resource_id, changetype, shift_id, resource_id, start_date, end_date ) 
                                  VALUES ( id_inner, "FU", shid_inner, resid_inner, startTime_inner, endTime_inner );
                UPDATE temp_shift_resource set startTime_inner=(endTime + INTERVAL 1 DAY) where shift_resource_id = id_inner;
            END IF;
    END IF;     
    END IF;
            END LOOP INNERLOOP;
    SET finish_flag = FALSE;
      END LOOP OUTERLOOP;
      CLOSE cr130;
      CLOSE cr131;



    COMMIT;

    END //
    DELIMITER ;

    call deleteabundant_fixshared_shiftResources();

2.) 我想做什么的描述:

基本上,我的桌子上摆满了轮班。由于代码错误,其中一些班次分配了错误的日期,我必须修复数据库。

  • 我必须遍历整个表,并比较分配给相同 resource_id(代表一个人)的行。因此,如果一个人有两个班次,例如(2016-05-10 到 2016-05-20)和(2016-05-15 到 2016-05-23),我必须修复它,以便其中一个将被修剪为 (2016-05-10 至 2016-05-14) 和 (2016-05-15 至 2016-05-23)。
  • 标记为 shift_id=9 的夜班班次绝对不能修改。
  • 如果进行了更改或删除,我将行插入到 repairchange 表中

3.) 程序运行,但什么也不做。我在数据库中有错误行的例子,一个例子是我上面写的那个。我怀疑它是嵌套循环,因为我想循环并通过同一张表获取,但我还没有找到任何东西。 我收到了消息

0 行受影响,1 个警告:1329 无数据 - 提取、选择或处理零行

但我以前见过这个,我的存储过程即使输出了这个警告也能正常工作。

欢迎任何想法或提示。感谢您的宝贵时间!

【问题讨论】:

  • 小更新:我添加了一行“select * from temp_shift_resource;”在 LOOPINNER 中,它运行了很多次,所以看起来循环正在工作,但获取可能没有?
  • 小更新 2:添加了 DATE(startTime),因此只比较日期,但不应该影响结果。

标签: mysql datetime stored-procedures cursor


【解决方案1】:

经过一番调试,我想通了:

我在两个循环之前打开了游标。这意味着在内循环的第一次遍历之后,光标位于表的最后一行的 +1 处,当新的外循环迭代开始第二次内循环迭代时,光标仍然在末尾位置。

因此它没有运行。我把内游标的开合换成了外循环,现在可以正常使用了。

【讨论】:

    猜你喜欢
    • 2012-05-05
    • 2013-06-20
    • 2011-04-02
    • 1970-01-01
    • 2013-11-13
    • 2013-08-05
    • 2021-11-21
    • 2013-09-28
    • 1970-01-01
    相关资源
    最近更新 更多