Почему в 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.