2016-06-01 3 views
0

У меня есть хранимая процедура среднего размера, описанная ниже. Моя проблема в том, что она ничего не делает, и я понятия не имею, почему.MySQL Хранимая процедура - Вложенный цикл по вине?

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.) Описание того, что я хочу сделать:

В принципе, у меня есть таблица полна workshifts. Из-за ошибок кода некоторые из этих сдвигов имеют неправильную дату, назначенную им, и я должен исправить базу данных.

  • Я должен бежать через всю таблицу и сравнить строки, которые назначены одному и тому же 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 Нет данных - ноль выбранных строк, выбранных, или обработаны

, но я видел это раньше, и мои хранимые процедуры работали даже если они выдают это предупреждение.

Любые идеи или советы приветствуются. Спасибо за ваше время!

+0

Небольшое обновление: я добавил строку «select * from temp_shift_resource;» в LOOPINNER он работал довольно много раз, поэтому кажется, что петли работают, но выборка может не быть? – Dragonturtle

+0

Маленькое обновление 2: добавлено DATE (startTime) вокруг, так что только даты будут сравниваться, но не должны беспокоить результат. – Dragonturtle

ответ

0

Я понял это, после довольно отладки:

Я открыл курсоры, прежде чем оба цикла. Это означало, что после первого прохода внутреннего цикла курсор стоял в +1 строки LAST таблицы, а когда новая итерация внешнего цикла начала вторую итерацию внутреннего цикла, курсор все еще находился в конце должность.

Таким образом, это не сработало. Я заменил открытие и закрытие внутреннего курсора во внешний цикл, и теперь он работает правильно.