Массовая сборка Oracle в коллекцию с использованием LOOP

http://www.oracle.com/technetwork/issue-archive/2008/08-mar/o28plsql-095155.html

На этой странице они упомянули, что:

Когда вы используете BULK COLLECT и коллекции для извлечения данных из вашего курсора, вы никогда не должны полагаться на атрибуты курсора, чтобы решить, прекратить ли ваш цикл и обработку данных.

Он упоминает, что для того, чтобы наш запрос обрабатывал все строки, мы должны

НЕ ИСПОЛЬЗОВАТЬ:

ВЫХОД ИЗ КОГДА

курсор%NOTFOUND;

и мы ДОЛЖНЫ ИСПОЛЬЗОВАТЬ:

ВЫХОД ИЗ КОГДА

collectionvariable.count=0;

Какова причина?

1 ответ

Решение

В статье четко указано, что при использовании cur%NOTFOUND это пропустит обработку некоторых записей.

Пожалуйста, проверьте автономный пример:

DECLARE
  TYPE item_tab IS TABLE OF PLS_INTEGER;
  l_item item_tab;
  CURSOR get_item_value IS
  SELECT LEVEL
  FROM dual
  CONNECT BY LEVEL <= 25;
BEGIN
  OPEN get_item_value;
  LOOP
     FETCH get_item_value BULK COLLECT INTO l_item LIMIT 10;  -- 10    10    5
     EXIT WHEN get_item_value%NOTFOUND;                       -- FALSE FALSE TRUE
     DBMS_OUTPUT.put_line(l_item.COUNT);       
  END LOOP;
  CLOSE get_item_value;
END;

Выход:

10
10
-- 5 record left

И вторая версия:

DECLARE
  TYPE item_tab IS TABLE OF PLS_INTEGER;
  l_item item_tab;
  CURSOR get_item_value IS
  SELECT LEVEL
  FROM dual
  CONNECT BY LEVEL <= 25;
BEGIN
  OPEN get_item_value;
  LOOP
     FETCH get_item_value BULK COLLECT INTO l_item LIMIT 10;   -- 10   10   5   0
     EXIT WHEN l_item.COUNT = 0;                               -- F    F    F   T
     DBMS_OUTPUT.put_line(l_item.COUNT);
  END LOOP;
  CLOSE get_item_value;
END;

Выход:

10
10
5
Другие вопросы по тегам