exception when no data found

Мы с вами, уже рассмотрели основные концепции определения и работы с курсорами. Но один аспект я упустил. А именно — неявные курсоры. Как вы уже, наверное, догадались, сам оператор SELECT представляет собой в прямом определении «КУРСОР», или еще это называют SQL-курсор! Откуда следует вывод, что любой оператор DML объемлит собой курсор. Так как, каждый оператор DML выполняется в пределах контекстной области и по этому имеет курсор указывающий на контекстную область. В отличии от явных, SQL-курсор не открывается и не закрывается. PL/SQL — сам неявно открывает SQL-курсор, обрабатывает SQL-оператор и закрывает SQL-курсор. Для SQL-курсора операторы FETCH, OPEN, CLOSE не нужны, но с ними можно использовать курсорные атрибуты, вот таким образом:

Давайте рассмотрим конкретный пример. В шаге 48 мы закончили работу с табличками PEOPLE и OLD_PEOPLE, если вы их удалили, то ничего страшного, просто вернитесь к шагу 46 и снова их создайте. Если они у вас остались, еще лучше! Итак, рассмотрим такой пример на основе таблички PEOPLE. Пусть нам нужно изменить поле NM в таблице PEOPLE, где поле ID содержит значение 555. Введем такой запрос, перед тем как:

Получаем (у меня так, у вас может отличаться, если таблица удалялась или вы делали что-то еще):

Но строки, где бы поле ID содержало 555, нет! Это нам и нужно, для того, чтобы продемонстрировать работу атрибута. Итак, запишем блок:

Посмотрим, что вышло:

Как видите, сработал атрибут SQL-курсора, %NOTFOUND. И, так как записи с таким значением поля ID не было, то с помощью оператора INSERT мы его добавили в таблицу PEOPLE! Все получилось верно! То же можно было сделать применив атрибут SQL-курсора, %ROWCOUNT. Вот так:

Смотрим содержимое таблицы PEOPLE:

И здесь все сработало верно, с той разницей, что мы применили атрибут SQL-курсора %ROWCOUNT. Теперь, давайте рассмотрим более сложную ситуацию, с применением атрибута SQL-курсора %NOTFOUND. А начнем, вот с чего. Я уже показывал вам оператор SELECT — формы SELECT . INTO. Но, не заострял внимание. Давайте немного отвлечемся и я все постараюсь объяснить. Итак, SELECT . INTO, это как бы некий эквивалент явного курсора с применением оператора выборки FETCH. Но сам по себе он является неявным курсором с выборкой в переменную. Понятно? Если нет, идем дальше. Если явный курсор вида:

Выбегает данные с помощью оператора FETCH, имеющего конструкцию, INTO в переменную v_gt. В свою очередь, являющейся одномерной коллекцией на основе курсора get_people. То запись вида:

Абсолютно ей эквивалентна. SELECT . INTO и есть неявный курсор с выборкой данных в одномерную коллекцию v_gt, так как они обе имеют один и тот же тип определения ROWTYPE и содержат четыре переменных вида:

С той лишь разницей, что первая объявлена на основе курсора (поля которого определены собственно выражением SELECT), а вторая на основе полей таблицы! Теперь, я надеюсь, что все неясности по поводу курсоров как явных, так и не явных у вас отпали сами собой. Безусловно, явные курсоры наиболее предпочтительны, так как более наглядны и применимы. Но если вам необходимо выполнить что-то очень простое, то можно использовать SELECT . INTO. В остальных случаях только явные курсоры! 🙂 Итак, собственно переходим к делу, если применить атрибут %NOTFOUND совместно с конструкцией SELECT . INTO, то он может не сработать, так как если SELECT . INTO не получит запись, то возникнет ошибка «ORA-1403 no data found». Для этого мы запишем вот такой блок и разберем его:

Как видите, сработал блок EXCEPTION (как с ним управляться — это чуть позже). Что и должно было произойти в нашем случае. Так как блок «SELECT * INTO. « не получил ни одной записи, то сработал блок EXCEPTION с условием NO_DATA_FOUND. Вот так производится обработка атрибутов при использовании неявных курсоров.

Нельзя создать приложение, которое будет безошибочно работать в любых ситуациях: возможны аппаратные сбои, невыявленные ошибки приложения и ошибки из-за некорректных действий пользователей приложения (клиентов). Если при этом программная ошибка произошла в блоке PL/SQL, вложенном в другой блок, а тот, в свою очередь, вложен в третий блок и т.д., то она может дойти до клиентского приложения. Чтобы устранить возможную отмену большого объема ранее выполненных операций и трафик из-за возвращаемых клиенту ошибок, чтобы посылать клиенту точные сообщения о причине ошибки и способе ее устранения (если она все же дошла до клиента), разработчики приложения должны предусматривать возможные программные ошибки и создавать процедуры, адекватно реагирующие на них.

В PL/SQL предусмотрен механизмы перехвата и обработки ошибок, возникающих при выполнении программы. Эти механизмы называются исключительными ситуациями.

Когда программа обнаруживает заданное условие ошибки, то вызывается соответствующая исключительная ситуация. Обработки исключительных ситуаций в программе производится в разделе EXCEPTION.
При обнаружении исключительной ситуации, обработка основного тела программы останавливается и управление передается соответствующему обработчику исключительной ситуации, который определяет дальнейшие действия.

В PL/SQL используются следующие типы исключительных ситуаций:

  • встроенные исключительные ситуации;
  • исключительные ситуации, определяемые пользователем;
  • обработчик OTHERS.

Встроенные исключительные ситуации

Oracle включает четырнадцать встроенных исключительных ситуаций, соответствующих типовым ошибкам, приведенным в следующей таблице:

Если в раздел EXCEPTION программы (блока) включена фраза

WHEN имя_исключения THEN
текст_обработчика_исключения;

с именем какого-либо встроенного исключения и возникла соответствующая ошибка, то вместо прекращения исполнения программы и выдачи типового сообщения об ошибке, будет исполняться созданный пользователем текст обработчика исключения.

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

Для выдачи сообщения об ошибке, обеспечения возврата в среду, из которой вызывалась текущая программа (блок) и отмены всех действий, выполненных в текущей транзакции, целесообразно использовать процедуру RAISE_APPLICATION_ERROR(errnum,errtext); где errnum – отрицательное целое число в диапазоне -20000 .. -20999 и errtext – символьная строка длиной до 2048 символов.

В приведенном ниже триггере «shtins» использованы два типа встроенных исключительных ситуаций: NO_DATA_FOUND и TOO_MANY_ROWS.

Так как в большом приложении могут часто повторяться встроенные или пользовательские исключительные ситуации, то целесообразно создать в базе данных таблицу (например, USERERR) с уникальными номерами (error_number) и текстами (error_text) исключений. Это позволит избежать определения лишних сообщений об ошибках и сделать их согласованными во всем приложении.

При использовании такой таблицы и процедуры RAISE_APPLICATION_ERROR надо описать в в разделе DECLARE блока две переменных (например, errnum типа NUMBER и errtext типа VARCHAR2) и использовать в обработчике исключений конструкцию:

Исключительные ситуации, определяемые пользователем

Кроме встроенных могут быть использованы собственные исключительные ситуации, имена которых необходимо описать в разделе DECLARE блока PL/SQL (например, err_stavka EXCEPTION). В разделе EXCEPTION блока должен быть описан соответствующий обработчик исключительной ситуации, например

В теле основной программы определяемые пользователем ошибки обычно проверяются с помощью операторов условия (IF…THEN). Для передачи управления обработчику пользовательской исключительной ситуации в случае обнаружения ошибки используется оператор RAISE имя_пользовательского_исключения Например

Обработчик OTHERS

Если исключительная ситуация не обрабатывается явным образом в блоке и для ее перехвата не используется обработчик OTHERS, то PL/SQL отменяет выполняемые блоком транзакции и возвращает необработанную исключительную ситуацию обратно в вызывающую среду.
Обработчик особых ситуаций OTHERS описывается последним в программе (блоке) для перехвата всех исключительных ситуаций, которые не были описаны в этой программе (блоке). Он может иметь вид

Запись опубликована 09.04.2010 в 7:12 дп и размещена в рубрике Oracle7 краткий справочник. Вы можете следить за обсуждением этой записи с помощью ленты RSS 2.0. Можно оставить комментарий или сделать обратную ссылку с вашего сайта.

I have a value that i dont know exactly in which column it is inserted. I can determine that since this table columns are named as C1. C99. I am going to find the column using the following code. But when the no data found exception is called, I cant start my loop again.

Оцените статью