ora 01403 no data found что за ошибка
Почему в Oracle не найдено данных ORA-01403?
если инструкция SELECT INTO не возвращает по крайней мере одну строку, Ora-01403 выбрасывается.
для каждой другой СУБД я знаю, что это нормально для выбора. Только Oracle обрабатывает SELECT таким образом.
почему?
на мой взгляд, вам не нужно это исключение. Это слишком накладно. Иногда это удобно, но вам нужно написать целый блок BEGIN, EXCEPTION, WHEN, END.
есть ли существенные причины я не видишь?
6 ответов
блок исключений не нужны, вы можете использовать его или нет, в зависимости от контекста.
здесь вы активно игнорируете исключение (процедура вернется успешно), но большую часть времени, если вы делаете выбор, вы хотите, чтобы не если он не возвращает строк, считать:
здесь я хочу, чтобы моя функция потерпела неудачу, если она вызывается с помощью empno этого не существует в таблице EMP. Я могу поймать исключение. чтобы вызвать значимое сообщение об ошибке (с raise_application_error ) но большую часть времени я доволен ORA-01403.
В общем, единственными исключениями, которые вы должны поймать, являются ожидаемые исключения (т. е. это не должно быть стандартом для ловли всех ORA-01403 или всех исключений в этом отношении).
но нам все равно нужно ответить на вопрос «почему возникает исключение в случае, когда SELECT не имеет данных для извлечения».
вероятно, IMHO, что проверка на SQLCODE = 100 будет часто пропускаться. Имеющий исключение, поднятое баранами, прямо в нос, что А) важное условие (данные не найдены) произошло, и Б) на это не было сделано никакого учета. IMO, имеющий PL / SQL engine, вызывает исключение, лучше, чем программа весело продолжает свой путь в предположении, что данные были получены, когда на самом деле это не так, что может привести ко всем видам других, чем веселых проблем.
поделиться и наслаждаться.
вы можете попробовать использовать MIN для предложения исключения использования.
тогда фиктивная переменная будет NULL
потому что вы делаете выбор, в который требуется ровно одна строка (больше строк также будет ошибкой).
Если у вас может быть одна строка или нет, вы можете использовать курсор.
Это не работа базы данных, чтобы решить для вас, что отсутствующая строка не является ошибкой, и просто установите значение null.
вы также можете использовать SQL макс или мин функции. Если строка не возвращается, то эти функции вернут NULL.
например: Выберите макс(колонка 1) В переменные из таблицы Где Column1 = ‘Value’;
на макс функция вернет максимальное значение или, если строка не будет возвращена, она вернет NULL.
ORA-01403: no data found
ORA-01403 Error Message: “No Data Found”
Some Oracle errors are a result of coding that does not prove quite as comprehensive as desired. These types of errors involve going back through your code and creating or editing your PL/SQL to compensate for the mistake. The ORA-01403 error (“no data found”) is representative of this type of Oracle problem, and while it involves a bit more coding savvy than other errors, the fix tends to be much more long term.
The ORA-01403 error derives from an SQL query meant to return all data requested, but no data was found. The error is often associated with SELECT INTO clauses, which fetch rows or sets of columns from a database. The data gathered is then inserted into a set of predefined variables. When a SELECT INTO query fails to return a single row, the ORA-01403 error is triggered in the system. The error can also be thrown when you attempt to select data from an uninitialized row in a table, or reading past the end of file with the UTF_FILE package. To initially work around the error, you need to terminate the processing data immediately, but what from there?
To avoid this type of situation from coming about, the best approach is to make sure that your PL/SQL has the proper exceptions coded. Without exceptions, the query will attempt to offer multiple values to the variables at the end of the query. If this continues and the exceptions are left non-existent or incomplete, each time the variable is accessed again the problem will compound.
Create an exception that would allow only one row to be retrieved each time the variable is accessed. Writing an exception that states “when NO_DATA_FOUND then return ‘No data in selected variable’”. By creating the proper exceptions, or at the least returning exceptions back to the proper calling block, the ORA-01403 can largely be skirted.
There are some occasions where NOLOGGING clauses can also trigger an ORA-01403. In some SQL operations, if you encounter a redo log record using a NOLOGGING clause, the record will be skipped and changes will be applied further along. If you attempt to access the updated files at a later date, the ORA-01403 error will occur. To fix this, re-create tables from the initial controlling database.
The good news is that the ORA-01403 error is highly preventable. By creating the proper exceptions, the program should now operate free of the error and remain that way until edited again. If you are unsure of how to write proper exceptions in Oracle, work with your licensed Oracle consultant on making sure that the proper coding infrastructure is in place so that your Oracle database operates smoothly.
Let’s Develop in Oracle
ORA-01403: no data found
ORA-01403: no data found
Cause: No data was found from the objects.
Action: There was no data from the objects which may be due to end of fetch
ORA-01403 is a very common error. ORA-01403 occurs with «SELECT INTO clause», which is designed to fetch only one record from a database and assign them in plsql variables. If SELECT INTO statement fails to fetch any record from database. ORA-01403 is generated.
Lets reproduce ORA-01403 with a very simple example:
In above example ORA-01403 was generated because there was no record in EMP table with EMPNO=10 causing SELECT INTO statement to return with 0 record.
SOLUTION:
When you use SELECT INTO statement, your PL/SQL code should be written to handle ORA-1403 exception. PL/SQL raises the predefined exception NO_DATA_FOUND if a SELECT INTO statement returns no rows. Following is the example which wrap up the SELECT INTO clause in proper exception handler.
One interesting thing about ORA-01403 is that if I use same «get_emp_name» function in SQL Statement even without exception handling, ORA-01403 will not be generated as in sql no data found quite simply means «no data found», stop. Let me show you this behavior by following example:
This is all I want to cover for ORA-01403 (NO_DATA_FOUND). I hope you have enjoyed reading this. Please put your feedback in comment box.
Часть 2. Идентификация событий происходящих в Oracle PL/SQL
Предисловие
Убедительная просьба, рассматривать данный текст только как продолжение к статье о «Событийной модели логирования». Эта статья будет полезна тем, у кого уже реализовано логирование событий в БД и кто хотел бы осуществлять сбор статистики и начать проводить аналитику этих событий. Только представьте, что ваша БД сможет информировать вас о критичных сбоях системы, накапливать информацию о событиях в БД (кол-во повторений, период повторений и т.д.). И всё это без использования стороннего ПО силами одного PL/SQL.
Введение
Модель логирования позволяет реализовать:
Единый подход в обработке и хранении событий (статья)
Собственную нумерацию и идентификацию событий происходящих в БД
Единый мониторинг событий (статья в разработке)
Анализ событий происходящих в БД (статья в разработке)
Описанные выше характеристики указаны в порядке нумерации и каждый следующий пункт (шаг) есть улучшение и усложнение существующей модели. Описание этой модели будет сложно выполнить в рамках одной статьи, поэтому опишем их последовательно. В этой (второй) статье создадим собственную нумерацию кодов для событий, а также создадим функционал идентификации событий происходящих в БД.
Для чего это нужно?
Для начала давайте рассмотрим пример. Вы реализовали логирование ошибок в вашей БД. С течением времени в ваш лог «прилетают» самые разнообразные ошибки. Предположим, имеются две ошибки вида «no_data_found» возникшие в двух разных процедурах при двух разных запросах (select). Первая ошибка возникла при попытке найти «email» клиента, что в принципе не является критичной ошибкой. Вторая ошибка возникла при попытке найти номер лицевого счета клиента, что вполне может являться критичной ошибкой. При этом если мы посмотрим в таблицу лога (из статьи), то увидим, что указанные ошибки будут храниться с одинаковым кодом 1403 (ORA-01403) в столбце msgcode. Более того, текст указанных ошибок будет практически аналогичным (текст полученный с помощью функции SQLERRM) за исключением имен объектов, на которых произошла ошибка. Для того чтобы понять является ли критичной конкретная ошибка, разработчику необходимо вникать в текст ошибки, смотреть в каком объекте возникла ошибка и на основе этой информации сделать вывод о срочности исправления. При этом, если мы сможем задать более четкое описание ошибки отличное от текста Oracle (SQLERRM), то это позволит упростить понимание причин возникновения и способов решения ошибки.
Как должно быть (в идеале)
Не найдена запись в таблице содержащей адреса электронной почты клиентов
ORA-01403: данные не найдены
USR0001: Не найден адрес электронной почты клиента (идентификатор клиента)
Не найдена запись в таблице содержащей лицевые счета клиентов
ORA-01403: данные не найдены
USR0002: Не найден лицевой счет клиента (идентификатор клиента)
Из этого примера видно, что одна и та же ошибка «no_data_found» (ORA-01403: данные не найдены) может иметь совершенно разное значение с точки зрения бизнес логики, а значит нам необходимо разработать механизм, который позволит идентифицировать каждое событие происходящее в БД как отдельное событие с нашим внутренним уникальным кодом и текстом события (отличную от Oracle). Таким образом мы решаем две проблемы:
1) В месте возникновения ошибки мы устанавливаем уникальный код ошибки. В будущем это позволяет достаточно быстро найти место возникновения ошибки. Также, наличие уникальных кодов позволяет нам произвести точечный подсчет повторений и на основании этой информации принять решение об устранении данной ошибки.
2) Дополнительный «читаемый» текст позволяет сильно упростить понимание ошибки. В таблице выше показано, как одна и та же ошибка может запутать или разъяснить пользователю сведения об ошибке.
Надеюсь мне удалось объяснить зачем необходимо кодировать события в таблице логов. Далее по тексту, будут введены термины «Архитектурный лог» и «Пользовательский лог». На примере процедуры поиска активного номера телефона клиента будет показано как и зачем создано разделение на архитектурный и пользовательский лог.
Архитектурное логирование событий
Давайте рассмотрим пример, имеется процедура поиска активного номера телефона принадлежащего конкретному клиенту (для примера его Предположим, что при постановке задачи для разработчика не было описания каких-либо особых условий т.е. по условиям задачи предполагалось, что для конкретного пользователя (id = 43, идентификатор передается в качестве параметра) в таблице client_telnumbers всегда будет хотя бы одна запись с номером телефона клиента и признаком «активный» (значение поля enddate равно дате 31.12.5999 23:59:59, что означает что номер используется клиентом. В случае, любой другой даты в указанном поле означает, что номер перестал быть активным и более не используется), поэтому наша процедура будет выглядеть примерно так:
Исходный код демонстрационной процедуры
Важно! Представленный код является примерным (примитивным) и служит только для демонстрации логирования в рамках данной статьи. В своих статьях я не выкладываю текст кода из реально действующих БД. Надеюсь, вы понимаете, что в реальности указанная процедура написана гораздо сложнее.
*Исходный код других используемых объектов смотрите в Git
Если мы будем использовать логирование ошибок как показано в предыдущей статье, то с течением времени обнаружим, что идентифицировать ошибки из данной процедуры будет сложно. Поэтому для всех ошибок попадающих в обработку исключения «WHEN OTHERS» реализована процедура pkg_msglog.p_log_archerr, которая при первом возникновении ошибки автоматически присваивает ей уникальный код и сохраняет ошибку в таблице лога. В дальнейшем, при повторении данной ошибки процедура найдет ранее созданный код и использует его при логировании в таблице лога.
В итоге, после добавления блока «архитектурного» логирования (строки с 18 по 24), наша процедура будет выглядеть следующим образом:
Исходный код демонстрационной процедуры
*Исходный код других используемых объектов смотрите в Git
Исходный код таблицы
Ограничение в таблице на комбинацию (Имя объекта, код ошибки SQLCODE). При первом появлении ошибки создается запись в таблице и генерируется код ошибки «SYS0000» + счетчик ошибок. При повторном появлении указанной ошибки будет взят уже сгенерированный ранее код ошибки.
рис. Пример содержимого таблицы messagecodes_arch
*Исходный код других используемых объектов смотрите в Git
Обратите внимание, что при использовании описанной модели «архитектурного» логирования у вас появляется функционал позволяющий максимально быстро реагировать на первое появление ошибки (в конкретной функции/процедуре). Для этого необходимо реализовать отдельный мониторинг архитектурных ошибок, который постараюсь продемонстрировать в следующей (третьей) статье. Использование процедуры pkg_msglog.p_log_archerr не требует каких-либо действий кроме описания входных параметров.
Таким образом мы можем создать базовый шаблон процедуры (функции), использование которого позволит вам гарантированно отлавливать все архитектурные ошибки в вашем коде.
Шаблон процедуры/функции с архитектурным логированием
Рекомендую использовать данный шаблон для построения «Событийной модели логирования».
*Исходный код других используемых объектов смотрите в Git
В рамках событийной модели логирования, предполагается, что все архитектурные ошибки будут исправляться отдельной задачей т.е. основная цель это устранить повторное появление ошибок с кодом «SYS****» в таблице лога. В указанной задаче вам необходимо либо устранить причины возникновения данной ошибки, либо добавить отдельную обработку ошибки отличную от «when others», которую в дальнейшем будем назвать «пользовательское» логирование (в рамках данного цикла статей).
Пользовательское логирование событий
Предположим, что однажды в нашей процедуре get_telnumber произошла «архитектурная ошибка». В частности, для конкретного пользователя в таблице client_telnumbers хранится два номера телефона с признаком «активный». В таком случае, процедура «упадёт» с ошибкой «ORA-01422: too_many_rows». При этом, наш функционал архитектурного логирования сгенерировал новый код ошибки «SYS0061» и создал запись в таблице лога.
рис. Код архитектурной ошибки SYS0061
Самое важно в такой ситуации это не откладывать «на потом» исправление архитектурных ошибок. В идеале, необходимо создать отдельную задачу (баг) и в рамках неё устранить ошибку.
Для этого в процедуре get_telnumber добавлено исключение (exception) «too_many_rows» пользовательского логирования. Также, был создан справочник пользовательских ошибок отличный от архитектурного справочника, тем что в него все записи добавляются разработчиком «вручную». Наверное это самое слабое место во всей архитектуре логирования. Предполагается, что разработчик должен описать исключение (exception) и создать для него уникальный код ошибки. Также, желательно к указанной ошибке сформулировать читаемый текст ошибки (для своих коллег, пользователя, техподдержки и т.д.), что бывает иногда очень сложным (из личного опыта).
Таблица пользовательских ошибок и процедура их «регистрации» будет выглядеть следующим образом:
Исходный код таблицы пользовательских ошибок и процедуры регистрации
Регистрация пользовательских ошибок производится процедурой p_insert_msgcode. На вход подается код и текст ошибки. В случае, если по указанному коду нет записей в справочнике messagecodes, то создается новая запись (производится регистрация). В случае, если по коду ошибки найдена запись, то производится сравнение текстов ошибки, в случае расхождений производится обновление текста, иначе работа процедуры завершается без изменений. Таким образом мы всегда можем корректировать текст ошибок.
Итого, содержимое справочника пользовательских ошибок будет выглядеть следующим образом:
рис. Пример содержимого справочника пользовательских ошибок
*Исходный код других используемых объектов смотрите в Git
После того, как мы «зарегистрировали» пользовательскую ошибку «USR0003» и добавив отдельную обработку пользовательского логирования (строки с 19 по 28), наша процедура get_telnumber будет выглядеть следующим образом:
Исходный код демонстрационной процедуры
*Исходный код других используемых объектов смотрите в Git
Давайте рассмотрим еще один пример (кейс из реального случая), в момент когда процедура get_telnumber по id клиента находит один «активный» номер телефона иногда возникает ситуация, что номер телефона не принадлежит мобильному оператору. Ситуации бывают разные иногда указанный номер мог быть номером городской телефонной сети, иногда номером международного оператора, а иногда вообще набор из нескольких цифр и т.д. Основным требованием от бизнес-заказчика было использование номера телефона российских операторов мобильной связи. Поэтому было решено добавить проверку соответствия найденного номера некому «корректному» шаблону (строки с 18 по 29). В случае обнаружения некорректного номера, логировать данное событие отдельным кодом «USR0004» и типом «WRN». Добавим функцию проверки корректности номера телефона, если номер соответствует шаблону (требованиям), то вернем номер телефона, иначе пустое значение.
Исходный код демонстрационной процедуры
*Исходный код других используемых объектов смотрите в Git
После сбора статистических данных по конкретной ошибке с кодом «USR0004», руководству стало понятно, что ошибка актуальна и количество ошибок с течением времени не только не уменьшается, а наоборот растет с линейной прогрессией. В дальнейшем, были выявлены источники «кривых» данных и были установлены внутренние требования по первичной обработке номера телефона клиентов. В итоге, со временем количество ошибок уменьшилось до нуля. И этого нельзя было добиться до тех пор, пока у всех участвующих лиц не возникло понимание о масштабе проблемы.
Выполняя самый банальный запрос в таблицу лога с группировкой по типу сообщения (msgtype), имени объекта (objname) и вашему внутреннему коду ошибки (msgcode) за отдельный квартал, вы сможете увидеть реальную картинку частоты возникновения той или иной ошибки. Как только в вашей БД появляется ошибка с большим количеством повторений вы всегда сможете выявить это событие и принять решение об устранении.
Исходный код запроса
рис. Пример результата запроса с группировкой
*Исходный код других используемых объектов смотрите в Git
Заключение
В заключении наверное скажу банальную вещь, о том что ваша БД является сложным механизмом ежесекундно выполняющая рутинные операции. Прямо сейчас в БД могут происходить различные ошибки. Критичные, которые вы исправляете практически сразу или некритичные, о которых вы можете вообще не знать. И если у вас нет информации о подобных ошибках, то возникает вопрос: «Нужно ли их вообще исправлять? Или можно подождать до тех пор, пока проблема не всплывёт?». Вопрос наверное «риторический».
Я же данной статьёй хотел показать один из способов ведения логирования с кодированием отдельных событий. Данный метод требует некоторых «обязательств» от разработчика и в нынешнее время этого тяжело добиться. В следующей статье постараюсь показать один из способов мониторинга ошибок основанный напрямую по кодам ошибок созданных в текущей статье.
ORA-01403: no data found for Select into
I am getting ORA-01403: no data found exception for the following query. What are the possibilities of this error?
How can I handle this error?
4 Answers 4
Although you have put a WHERE condition, a better way would be to handle case of record not found or ‘No Data Found’ error. I would write above code with wrapping the SELECT statement with it’s own BEGIN/EXCEPTION/END block.
Code could be something like this:
If the standard exception handling described by Sandeep seems to much overhead (like in my case) and you’re fine with a NULL or some individual value), you might just transform it like this:
=> no ORA-01403 raised:
Probably because your Query
is not returning any rows
See this for reference.
Not the answer you’re looking for? Browse other questions tagged oracle or ask your own question.
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.12.16.41042
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.