Почему не срабатывает условие на `sql%notfound`?
Вот интересно, почему этот блок кода не работает. В таблице нет ни одной записи сid=1:
DECLARE
VAR_NAME VARCHAR2(100);
VAR_ID NUMBER := 1;
BEGIN
SELECT NAME INTO VAR_NAME
FROM SUPPLIER
WHERE ID = VAR_ID;
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('DATA NOT FOUND');
ELSIF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('DATA FOUND');
END IF;
END;
Получаю ошибку:
ORA-01403: no data found
Но почему не срабатывает условие на sql%notfound?
Свободный перевод вопроса pl sql %NOTFOUND от участника @user1050619
Ответы (1 шт):
Хотя атрибуты неявного курсора SQL%FOUND, SQL%NOTFOUND или SQL%ROWCOUNT доступны после выполнения SELECT ... INTO, но проверять их значения не имеет никакого смысла.
Статическикий запрос SELECT ... INTO завершится без ошибок, только, если его результат - одна единственная запись. Значения атрибутов неявного курсора в этом случае будут одни и те же.
В противном случае, вызывается исключение:
NO_DATA_FOUND- если запрос не возвращает ни одной записиTOO_MANY_ROWS- если запрос возвращает более одной записи
Поэтому, SELECT ... INTO следует заключить в отдельный блок с веткой обработки исключений:
<<my>>
declare
name varchar2 (100);
id number := 1;
begin
begin
select name into name
from supplier
where id = my.id;
dbms_output.put_line('one row found');
exception
when no_data_found then
dbms_output.put_line ('data not found');
when too_many_rows then
dbms_output.put_line ('too many rows found');
end;
dbms_output.put_line ('sql%found/notfound/rowcount='||
case sql%found when true then 'true' else 'false' end||'/'||
case sql%notfound when true then 'true' else 'false' end||'/'||sql%rowcount);
end;
/
data not found
sql%found/notfound/rowcount=false/true/0