Почему в Oracle не найдено данных ORA-01403?

если инструкция SELECT INTO не возвращает по крайней мере одну строку, Ora-01403 выбрасывается.

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

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.

есть ли существенные причины я не видишь?

6 ответов


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

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

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 или всех исключений в этом отношении).


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

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

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

вероятно, IMHO, что проверка на SQLCODE = 100 будет часто пропускаться. Имеющий исключение, поднятое баранами, прямо в нос, что А) важное условие (данные не найдены) произошло, и Б) на это не было сделано никакого учета. IMO, имеющий PL / SQL engine, вызывает исключение, лучше, чем программа весело продолжает свой путь в предположении, что данные были получены, когда на самом деле это не так, что может привести ко всем видам других, чем веселых проблем.

поделиться и наслаждаться.


вы можете попробовать использовать MIN для предложения исключения использования.

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

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


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

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

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


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


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

например: Выберите макс(колонка 1) В переменные из таблицы Где Column1 = 'Value';

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