Я писал базовые веб-приложения в течение года (для базы данных Oracle), и, поскольку функции довольно просты, большинство из нас используют обычные циклы FOR для получения наших данных:
for i in (select * from STUDENTS) loop
htp.prn(i.student_last_name || ', ' || i.student_first_name || ' ' || i.student_dob);
end loop;
Но курсоры кажутся «правильным» способом сделать что-то. Я могу найти много информации о том, что такое курсоры, и о различных способах их обхода, но не могу найти вескую причину, по которой их можно использовать поверх обычных циклов FOR. Это зависит от потребностей процедуры? Есть ли присущие мне преимущества, о которых я должен знать?
FOR
просто еще один способ использовать курсоры. Смотрите документы: docs.oracle.com/cd/E11882_01/appdev.112/e10472/… В любом случае, что делает htp.prn ()?FOR
Я думаю, что для такого рода вещей цикл гораздо более читабелен. Я склонен использовать «настоящие» курсоры, только если мне нужно сделать шаг назад, а не только вперед. Я задал этот другой вопрос, потому что я могу представить табличную функцию вместоhtp.prn()
.Ответы:
Курсор может быть явным или неявным, и любой тип может использоваться в цикле FOR. На самом деле есть два аспекта вашего вопроса.
Зачем использовать явный курсорный цикл FOR над неявным курсорным циклом FOR?
Зачем использовать цикл с FETCH, а не цикл FOR, который не имеет явного FETCH?
Вот некоторая полезная информация из документации.
Пример неявного курсора FOR LOOP
Пример явного курсора для цикла
Неявный курсор
Явный курсор
Курсор для операторов LOOP
источник
Код, который вы разместили, использует курсор. Это использует неявный цикл курсора.
Существуют случаи, когда использование явного цикла курсора (т. Е. Объявление переменной CURSOR в разделе объявлений) дает либо более чистый код, либо лучшую производительность
student_cursor
вместо включения 30-строчного SQL-оператора, в который встроена куча логики. Например, если вы распечатывали всех студентов, которые были допущены к выпуску и которые включали в себя присоединение к таблицам, в которых были свои академические записи, требования к программе их степеней, таблицы с информацией об академических трюмах, таблицы с информацией о просроченных библиотечных книгах, таблицы с информацией о невыплаченных сборах, административных переопределениях и т. д., вероятно, имеет смысл реорганизовать код, чтобы этот запрос не застрял в середине кода, который связан с представлением списка пользователю. Это может включать создание представления, которое инкапсулирует всю эту логику. Или это может включать создание явного курсора, который был объявлен либо как часть текущего блока PL / SQL, либо в каком-либо блоке PL / SQL более высокого уровня (т.е. курсор, объявленный в пакете), поэтому его можно использовать повторно. Или это может включать в себя что-то еще для инкапсуляции и повторного использования (скажем, вместо этого создание конвейерной табличной функции).htp.prn
, то,BULK COLLECT
вероятно, ничего не купит. Однако в других случаях это может привести к значительному повышению производительности.источник
Я вижу, что многие разработчики используют явные курсоры вместо неявных курсоров по старой привычке. Это потому, что в Oracle версии 7 это всегда был более эффективный путь. В наши дни, как правило, все наоборот. Специально с оптимизатором, который при необходимости может переписать неявный курсор для циклов для массового сбора.
источник
Недавно мне пришлось переписать несколько запросов из неявного цикла FOR в явные курсоры. Причина была в том, что запросы извлекали данные из внешней базы данных по ссылке, и эта база данных отличалась от нашей локальной базы данных. При переносе данных из неявного курсора в локально определенный тип записи возникали загадочные периодические ошибки (только в определенных конкретных строках). Наш DBA объяснил нам это, мы бы не смогли разобраться в этом сами. Кажется, это ошибка в Oracle, о которой сообщалось.
Нам посоветовали переписать все, используя явные курсоры, и ошибка исчезла.
Не основная причина, по которой вы можете использовать явное, а не явное, но стоит обратить внимание.
РЕДАКТИРОВАТЬ: Oracle 12c.
источник