PLSQL вставка в цикл - PullRequest
       2

PLSQL вставка в цикл

1 голос
/ 27 марта 2019

Я получил скрипт PL / SQL для вставки данных из другой таблицы, но результат оказался не таким, как я ожидал.Вставка в таблицу BBB сохраняет только первый ряд циклов d_rec.Когда я пытался напечатать / вывести d-Rec в другом sql, он дал мне все строки, которые были сохранены в таблице yyy.

Я уже пытался использовать курсор, но результат все тот же.

DECLARE
GROUP_SEQ NUMBER;
TRANS_SEQ NUMBER;
ID NUMBER;
PP NUMBER := 1;
TRANS_ID NUMBER;
TRANS_SUM NUMBER;
UNIT VARCHAR(6);
DEBET NUMBER;
CREDIT NUMBER;

BEGIN
FOR v_rec in (SELECT unit from xxx)
LOOP
   FOR d_rec in (SELECT ID, TRANS_SUM, UNIT from yyy where unit = v_rec.unit )
   LOOP

     UPDATE YYY_SEQUENCE 
       SET SEQ_COUNT = SEQ_COUNT + 1
       WHERE SEQ_NAME = 'GROUP_SEQ'
       RETURNING SEQ_COUNT 
       INTO GROUP_SEQ;
       COMMIT;

      INSERT INTO AAA (ID, SEQ) VALUES (ID, GROUP_SEQ);
      WHILE PP <= 4
      LOOP
         UPDATE YYY_SEQUENCE 
         SET SEQ_COUNT = SEQ_COUNT + 1
         WHERE SEQ_NAME = 'TRANS_SEQ'
         RETURNING SEQ_COUNT 
         INTO TRANS_SEQ;
         COMMIT;

         IF (PP < 3) THEN
             DEBET := TRANS_SUM;
             CREDIT := 0;
         ELSE             
             DEBET := 0;
             CREDIT := TRANS_SUM;
         END IF;
         PP := PP +1;
         INSERT INTO BBB(ID, SEQ, UNIT, DEBET, CREDIT) VALUES (ID, TRANS_SEQ, UNIT, DEBET, CREDIT);
         COMMIT;
      END LOOP;
   END LOOP;
PP :=1;
END LOOP;
END

Первая вставка дает мне все строки в данных d_rec.Но вторая вставка дает мне только первую строку данных d_rec.

1 Ответ

0 голосов
/ 27 марта 2019

Вы сбрасываете счетчик PP после цикла d_rec внутри цикла v_rec; это означает, что как только он был увеличен до 4 для первых d_rec для юнита, последующие d_rec итерации пропускают самый внутренний цикл - потому что PP <= 4 никогда не выполняется для них.

Быстрое решение - переместить этот сброс в цикл:

...
      END LOOP;
      -- reset PP after this loop
      PP :=1;
   END LOOP;
   -- instead of after this loop
   --PP :=1;
END LOOP;
END

Но, вероятно, будет понятно, если вы сбросите настройки непосредственно перед использованием:

...
      INSERT INTO AAA (ID, SEQ) VALUES (ID, GROUP_SEQ);
      -- reset here
      PP := 1;
      WHILE PP <= 4
      LOOP
         PP := PP +1;

         ...

         IF (PP < 3) THEN
             DEBET := TRANS_SUM;
             CREDIT := 0;
         ELSE             
             DEBET := 0;
             CREDIT := TRANS_SUM;
         END IF;

         INSERT INTO BBB(ID, SEQ, UNIT, DEBET, CREDIT) VALUES (ID, TRANS_SEQ, UNIT, DEBET, CREDIT);
         COMMIT;
      END LOOP;
   END LOOP;
END LOOP;
END

Или вообще избавиться от явной переменной - чтобы ее не нужно было объявлять, сбрасывать или увеличивать - и вместо нее использовать a для цикла :

...
      INSERT INTO AAA (ID, SEQ) VALUES (ID, GROUP_SEQ);
      FOR PP IN 1..4
      LOOP
         ...

         IF (PP < 3) THEN
             DEBET := TRANS_SUM;
             CREDIT := 0;
         ELSE             
             DEBET := 0;
             CREDIT := TRANS_SUM;
         END IF;

         INSERT INTO BBB(ID, SEQ, UNIT, DEBET, CREDIT) VALUES (ID, TRANS_SEQ, UNIT, DEBET, CREDIT);
         COMMIT;
      END LOOP;
   END LOOP;
END LOOP;
END

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...