MySQL 存储过程 - 嵌套循环出错?
MySQL Stored Procedure - Nested loop at fault?
我在下面有一个中型存储过程。我的问题是它什么也没做,我不知道为什么。
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.) 我想做的事情的描述:
基本上,我 table 经常轮班。由于代码错误,其中一些班次分配了错误的日期,我必须修复数据库。
- 我必须运行遍历整个table,并比较分配给相同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 table
3.) 程序 运行s,但什么也不做。我在数据库中有错误行的例子,一个例子就是我上面写的那个。我怀疑这是嵌套循环,因为我想通过相同的 table 循环和获取,但我还没有找到任何关于它的东西。
我收到消息
0 行受影响,1 条警告:1329 无数据 - 提取、选择或处理的行为零
但我以前见过这个,即使它们输出了这个警告,我的存储过程也能正常工作。
欢迎任何想法或提示。感谢您的宝贵时间!
我想通了,经过相当多的调试:
我在两个循环之前都打开了游标。这意味着在内循环的第一次遍历之后,光标位于 table 的最后一行的 +1,而当新的外循环迭代开始第二次内循环迭代时,光标是仍处于结束位置。
因此它没有运行。我把内游标打开和关闭替换成外循环,现在可以正常使用了。
我在下面有一个中型存储过程。我的问题是它什么也没做,我不知道为什么。
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.) 我想做的事情的描述:
基本上,我 table 经常轮班。由于代码错误,其中一些班次分配了错误的日期,我必须修复数据库。
- 我必须运行遍历整个table,并比较分配给相同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 table
3.) 程序 运行s,但什么也不做。我在数据库中有错误行的例子,一个例子就是我上面写的那个。我怀疑这是嵌套循环,因为我想通过相同的 table 循环和获取,但我还没有找到任何关于它的东西。 我收到消息
0 行受影响,1 条警告:1329 无数据 - 提取、选择或处理的行为零
但我以前见过这个,即使它们输出了这个警告,我的存储过程也能正常工作。
欢迎任何想法或提示。感谢您的宝贵时间!
我想通了,经过相当多的调试:
我在两个循环之前都打开了游标。这意味着在内循环的第一次遍历之后,光标位于 table 的最后一行的 +1,而当新的外循环迭代开始第二次内循环迭代时,光标是仍处于结束位置。
因此它没有运行。我把内游标打开和关闭替换成外循环,现在可以正常使用了。