DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

DML и обработка исключений

При возникновении исключения в PL/SQL-блоке Oracle не производит отмену (откат) изменений, внесенных командами DML этого блока. Выбор поведения приложения в подобной ситуации осуществляет тот, кто управляет логикой транзакций приложения, то есть сам программист. При этом необходимо учитывать следующие соображения:
Если ваш блок является автономной транзакцией (мы поговорим о них чуть позже в этой же главе), то при возникновении исключения необходимо выполнить откат или фиксацию изменений (обычно выполняется откат).
Для ограничения области отката можно использовать точки сохранения. Другими словами, можно выполнить откат изменений вплоть до некоторой точки сохранения, сохранив тем самым часть изменений, выполненных в рамках сеанса (подробно о точках сохранения мы также поговорим далее в этой главе).
Если исключение распространяется за пределы самого внешнего блока (то есть остается необработанным), то в большинстве сред выполнения PL/SQL, таких как SQL*Plus, автоматически производится безусловный (unqualified) откат, и все сделанные ранее изменения отменяются.
Пакетные операции DML и оператор FORALL
В версии Oracle8i Database возможности по использованию DML в PL/ SQL были значительно усовершенствованы за счет появления оператора FORALL. Оператор FORALL указывает исполняющему ядру PL/SQL на необходимость пакетного связывания в команде SQL всех элементов одной или нескольких коллекций перед их отправкой ядру SQL. Какая от этого может быть польза? Все мы знаем о том, что PL/SQL тесно
связан с ядром SQL базы данных Oracle. PL/SQL - это лучший язык программирования для баз данных Oracle (даже несмотря на то, что теперь вы можете, по крайней мере, теоретически, использовать в тех же целях и язык Java).
Но такая тесная интеграция не обязательно означает отсутствие накладных расходов при запуске SQL из PL/SQL-программы. Когда исполняющее ядро PL/SQL обрабатывает блок кода, оно исполняет процедурные команды внутри собственного ядра, а команды SQL пересылает ядру SQL, где они исполняются, и результат (при необходимости) возвращается в ядро PL/SQL.
Передача управления от ядра PL/SQL ядру SQL и обратно называется переключением контекста. Каждое такое переключение означает дополнительные издержки. В определенных ситуациях таких переключений может быть очень много, что существенно снижет производительность. В версии Oracle8i Database появляются две возможности объединения нескольких переключений контекста в одно, таким образом повышая производительность приложения. Речь идет об операторе FORALL и предложении BULK COLLECT (которое было рассмотрено ранее).
При пакетном связывании команды и передаче ее ядру SQL команда исполняется один раз для каждого индекса из диапазона. Другими словами, выполняются те же команды SQL, но все они выполняются в рамках одного обращения к ядру SQL, то есть происходит всего одно переключение контекста (рис. 1.4).

Синтаксис оператора FORALL
Несмотря на то что оператор FORALL включает в себя схему итерации (в соответствии с которой он перебирает элементы коллекции), он не
где: индекс_строки
Определяет коллекцию, элементы которой будет перебирать оператор FORALL.
нижняя_граница
Начальное значение индекса (строки или элемента коллекции) для выполнения операции.
верхняя_граница
Конечное значение индекса (строки или элемента коллекции) для выполнения операции.
sql_команда
Команда SQL, которая должна быть выполнена для каждого элемента коллекции.
индексирующая_коллекция
Коллекция PL/SQL, используемая для выбора индексов в связанном массиве, заданном в sql_команде. Возможность использования операторов INDICES_OF и VALUES_OF появилась в версии Oracle Database 10g.
SAVE EXCEPTIONS
Необязательное предложение, которое сообщает оператору FORALL о необходимости обработки всех строк с сохранением всех возникающих исключений.
При работе с FORALL необходимо соблюдать следующие правила:
Телом оператора FORALL должна являться только одна команда DML:
INSERT, UPDATE или DELETE.
является циклом FOR. Следовательно, в нем нет ключевых слов LOOP и END LOOP. Синтаксис оператора FORALL таков:
Оператор DML должен ссылаться на элементы коллекции посредством переменной индекс_строки, которая задана в операторе FORALL. Область действия переменной индекс_строки ограничивается оператором FORALL; вы не можете ссылаться на нее извне этого оператора. Однако обратите внимание, что верхняя и нижняя границы коллекций не обязательно должны охватывать все содержимое коллекций.
Не следует объявлять переменную индекс_строки. Она объявляется неявно как переменная типа PLS_INTEGER ядром PL/SQL.
Верхняя и нижняя границы должны задавать допустимый диапазон последовательных номеров индексов для коллекции (коллекций), заданных в команде SQL. Для разреженной коллекции будет сгенерирована следующая ошибка:

Пример такой ситуации приведен в файле diffcount.sql, который можно найти на веб-сайте книги.
Тем не менее Oracle Database 10^ поддерживает операторы INDICES OF и VALUES OF для разреженных коллекций (в которых пропущены какие-то элементы).
вызовет при компиляции такую ошибку:
вызовет появление такой ошибки:
В операторе DML нельзя ссылаться на отдельные поля коллекций записей. Даже в случае, когда поле коллекции является коллекцией скаляров или коллекцией более сложных объектов, разрешено ссылаться только на строку коллекции целиком. Например, такой код:
• Индекс элемента коллекции, заданной в операторе DML, не может быть выражением. Например, выполнение следующего фрагмента
Примеры FORALL
Рассмотрим несколько примеров использования оператора FORALL:
• Перепишем процедуру order_books с использованием FORALL:
Все изменения заключаются в замене FOR на FORALL и удалении ключевых слов LOOP и END LOOP. При этом FORALL передает команде SQL все строки, определенные в двух коллекциях. На рис. 1.4 показано, как организовано исполнение подобной процедуры.
• Используем индексы, определенные в одной коллекции, для определения того, какие строки из массива связывания (коллекции, за-
В следующем примере будет показано, как оператор DML может ссылаться на несколько коллекций. Возьмем три коллекции: denial, patient_name и illnesses. Проиндексированы элементы только двух первых коллекций, так что отдельные элементы этих коллекций будут переданы по индексу в каждую команду INSERT. Третьим столбцом таблицы health_coverage является коллекция, перечисляющая некоторые условия. Так как ядро PL/SQL выполняет пакетное связывание только для проиндексированных коллекций, то коллекция illnesses будет целиком помещена в третий столбец каждой вставляемой строки:

• Используем предложение RETURNING в операторе FORALL для извлечения информации о каждой отдельной команде DELETE. Следует помнить, что предложение RETURNING оператора FORALL должно использовать вложенное предложение BULK COLLECT INTO («пакетная» операция для запросов):
 









jAntivirus