Can %NOTFOUND return null after a fetch?
I can find a situation where a fetch can fail:
declare i integer; cursor c is select 1 / 0 from dual;begin open c; begin fetch c into i; exception when others then dbms_output.put_line('ex'); end; if c%notfound is null then dbms_output.put_line('null'); elsif c%notfound then dbms_output.put_line('true'); else dbms_output.put_line('false'); end if; close c;end;
But this only makes your question stronger since it will evaluate to null, neither in 10g nor in 11g ...
I think the part that's tripping you up is this:
If FETCH never executes successfully, the EXIT WHEN condition is never TRUE and the loop is never exited.
Somewhere in the past there must have been a code example which looked like this:
LOOP FETCH c1 INTO name; EXIT WHEN c1%NOTFOUND; -- Do stuffEND LOOP;
Given this chunk of code, then the statement rings true. If the fetch never executes (fails), then %NOTFOUND will be null. The EXIT WHEN
condition will not evaluate to TRUE (null evaluates to false). Then, indeed, the loop will continue forever.
This is a situation that is easily tested:
SET SERVEROUT ON;DECLARE -- this cursor returns a single row CURSOR c1 IS SELECT 1 FROM dual WHERE rownum = 1; -- this cursor returns no rows CURSOR c2 IS SELECT 1 FROM dual WHERE 1=0; v1 number;BEGIN OPEN c1; FETCH c1 INTO v1; -- this returns a record FETCH c1 INTO v1; -- this does not return a record IF c1%NOTFOUND THEN dbms_output.put_line('c1%NOTFOUND: TRUE'); ELSIF c1%NOTFOUND IS NULL THEN dbms_output.put_line('c1%NOTFOUND: NULL'); ELSE dbms_output.put_line('c1%NOTFOUND: FALSE'); END IF; CLOSE c1; OPEN c2; FETCH c2 INTO v1; -- this does not return a record IF c2%NOTFOUND THEN dbms_output.put_line('c2%NOTFOUND: TRUE'); ELSIF c2%NOTFOUND IS NULL THEN dbms_output.put_line('c2%NOTFOUND: NULL'); ELSE dbms_output.put_line('c2%NOTFOUND: FALSE'); END IF; CLOSE c2;END;/
The output of the script on Oracle APEX 4.1 is (I think APEX is running Oracle 11gR2, but you can easily run the script on any version):
c1%NOTFOUND: TRUEc2%NOTFOUND: TRUE
Based on this test, %NOTFOUND
will not be NULL after a fetch has been executed. This matches what the 10g and 11g documentation says in the initial description of the %NOTFOUND
attribute. The note about the loop never exiting must be from an old version of the example. Since it's just a note, I'd says it's safe to trust the initial description and disregard the note.