Почему no_data_found ORA-01403 является исключением в Oracle? - PullRequest
17 голосов
/ 15 октября 2010

Если инструкция SELECT INTO не возвращает хотя бы одну строку, генерируется ORA-01403.

Для любой другой СУБД, которую я знаю, это нормально для SELECT. Только Oracle рассматривает SELECT INTO таким образом.

CREATE OR REPLACE PROCEDURE no_data_proc IS
   dummy dual.dummy%TYPE;
BEGIN
  BEGIN 
     SELECT dummy  
       INTO dummy
       FROM dual
      WHERE dummy = 'Y';   
  EXCEPTION 
     WHEN no_data_found THEN
        dbms_output.put_line('Why is this needed?');
  END;
END no_data_proc;

Почему?

По-моему, вам не нужно это исключение на самом деле. Это слишком много накладных расходов. Иногда это удобно, но вы должны написать целый блок BEGIN, EXCEPTION, WHEN, END.

Есть какие-то существенные причины, которые я не вижу?

Ответы [ 7 ]

19 голосов
/ 15 октября 2010

Блок исключений не необходим , вы можете использовать его или нет, в зависимости от контекста.

Здесь вы активно игнорируете исключение (процедура вернется успешно), но большинствоесли вы делаете SELECT INTO, вы хотите, чтобы он fail , если он не возвращает строку, рассмотрим:

PROCEDURE update_employee_salary (p_empno) IS
   l_salary NUMBER;
BEGIN
   SELECT sal INTO l_salary FROM emp WHERE empno = p_empno FOR UPDATE;
   /* do something with emp data */
END;

Здесь я хочу, чтобы моя функция не работала, еслион вызывается с empno, которого нет в таблице EMP.Я мог бы поймать исключение, чтобы вызвать значимое сообщение об ошибке (с raise_application_error), но большую часть времени я доволен ORA-01403.

В общем, единственные исключения, которые вы должны поймать, это ожидаемыеисключения (то есть это не должно быть стандартом для перехвата всех ORA-01403 или всех исключений по этому вопросу).

12 голосов
/ 15 октября 2010

Но нам все еще нужно ответить на вопрос «почему возникает исключение в случае, когда SELECT не имеет данных для извлечения».

Я считаю, что это сделано, потому что это обычная ситуация, которую в противном случае можно было бы упустить из виду. Написание кода так, как будто он всегда ожидает найти данные, является обычным делом, и если мы должны были включить проверку ошибок, такую ​​как

SELECT <something...>
IF SQLCODE = 100 THEN -- No data found
  <no-data handler>
END IF

вполне вероятно, что ИМХО проверка на SQLCODE = 100 будет часто пропускаться. Возникновение исключения приводит к тому, что A) произошло важное условие (данные не найдены), и B) НИКАКОЕ ПРЕДОСТАВЛЕНИЕ НЕ СДЕЛАНО ДЛЯ ЭТОГО. IMO, использующий механизм PL / SQL, вызывает исключение лучше, чем программа, продолжающая весело продолжать свой путь, исходя из предположения, что данные были извлечены, хотя на самом деле это не так, что может привести к всевозможным, кроме веселых, проблемам.

Делись и наслаждайся.

7 голосов
/ 15 октября 2010

Вы можете попробовать использовать MIN, чтобы не использовать предложение EXCEPTION.

 SELECT MIN(dummy)  
   INTO dummy
   FROM dual
  WHERE dummy = 'Y'; 

тогда фиктивная переменная будет NULL

3 голосов
/ 15 октября 2010

Поскольку вы выполняете SELECT INTO, для которого требуется ровно одна строка (большее количество строк также будет ошибкой).

Если у вас может быть одна строка или нет, вы можете использовать курсор.

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

2 голосов
/ 18 ноября 2015

Вы также можете использовать функции sql MAX или MIN . Если ни одна строка не возвращается, эти функции вернут NULL .

Например: Выберите MAX (колонка 1) В переменную Из таблицы Где Column1 = 'Значение';

Функция MAX вернет максимальное значение или, если строка не будет возвращена, то вернет NULL.

1 голос
/ 25 июня 2019

MAX функция работает, она не выдает ошибку ORA-01403 работает, когда NULL возвращается, выбрав INTO

1 голос
/ 16 октября 2010

Поскольку неясно, что должен делать механизм PL / SQL - должен ли он выйти из блока? Должен ли он нажимать с NULL в переменной? Что если в следующем блоке вы попытаетесь вставить это в столбец NOT NULL, как он должен сообщить о местонахождении ошибки? Сделав это исключение, вы должны быть откровенным об этом.

...