Can %NOTFOUND return null after a fetch? Can %NOTFOUND return null after a fetch? oracle oracle

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.