Discussion:
PL/SQL, 8i: Better way to handle implicit cursor's data_not_found exception?
(too old to reply)
Thomas T
2003-09-24 16:11:46 UTC
Permalink
Just a quick question with PL/SQL and Oracle 8i (under Win2k o/s)!

I wrote an implicit cursor that would look up one value, and used the
%NOTFOUND property to check to see if the cursor returned a value or not. I
tested the code, and my user-defined exception wasn't raised, the "when
others" loop caught it! I removed the "when others" clause, re-ran the
procedure, and got a no_data_found exception that pointed to my implicit
cursor. In reading up, I found out that SQL%NOTFOUND is only valid for
group functions! Too bad. I think the following code snippet is the only
way to tell if the implicit cursor threw the no_data_found, or if it came
from elsewhere. Any thoughts? Is there anything slightly more
sophisticated then using null as a flag? It brings back flashbacks of
using -999 to determine "end of data" in text streams...

I'm not using an explicit cursor and a for loop because the value I need
isn't needed often; it's only needed if a value in the main "for" loop
changes. An explicit cursor seemed like overkill to me, because I'd be
opening and closing it every time I needed a value. (I'd need to make a
parameterized explicit cursor.) Or should I just go explicit? I usually
use explicit cursors, unless, like this situation, the value is only
retrieved once or very few times.

set serveroutput on
declare
mynum number;
begin
mynum:= 3; --old value from prior operation

mynum:=null; --now need to get new value, so reset value before query
select 5
into mynum
from dual
where 0=5; --yes this was done on purpose
if SQL%NOTFOUND then --doesn't execute b/c no_data_found is raised
dbms_output.put_line('wasn''t found');
end if;

dbms_output.put_line('mynum is ' || mynum);
exception
when no_data_found then
dbms_output.put_line('error handler');
if mynum is null then
dbms_output.put_line('mynum is null so I know where error was');
else
dbms_output.put_line('Unexpected ''no data found'' error');
end if;
end;
/

As you can tell, I just typed this up right in SQL*Plus as a test. Thanks!

-Thomas
Sybrand Bakker
2003-09-24 17:10:12 UTC
Permalink
Post by Thomas T
I wrote an implicit cursor that would look up one value, and used the
%NOTFOUND property to check to see if the cursor returned a value or not. I
tested the code, and my user-defined exception wasn't raised, the "when
others" loop caught it! I removed the "when others" clause, re-ran the
procedure, and got a no_data_found exception that pointed to my implicit
cursor. In reading up, I found out that SQL%NOTFOUND is only valid for
group functions! Too bad. I think the following code snippet is the only
way to tell if the implicit cursor threw the no_data_found, or if it came
from elsewhere. Any thoughts? Is there anything slightly more
sophisticated then using null as a flag? It brings back flashbacks of
using -999 to determine "end of data" in text streams...
An implicit cursor will *ALWAYS* raise a NO_DATA_FOUND exception.
You need to trap the NO_DATA_FOUND exception.
Simply enclose the implict cursor in it's own begin end block, trap
the exception and you are done. (Apart from reading the documentation
more closely, that is)




Sybrand Bakker, Senior Oracle DBA

To reply remove -verwijderdit from my e-mail address
Thomas T
2003-09-26 21:06:26 UTC
Permalink
Post by Sybrand Bakker
Post by Thomas T
I wrote an implicit cursor that would look up one value, and used the
%NOTFOUND property to check to see if the cursor returned a value or not.
I
Post by Sybrand Bakker
Post by Thomas T
tested the code, and my user-defined exception wasn't raised, the "when
others" loop caught it! I removed the "when others" clause, re-ran the
procedure, and got a no_data_found exception that pointed to my implicit
cursor. In reading up, I found out that SQL%NOTFOUND is only valid for
group functions! Too bad. I think the following code snippet is the only
way to tell if the implicit cursor threw the no_data_found, or if it came
from elsewhere. Any thoughts? Is there anything slightly more
sophisticated then using null as a flag? It brings back flashbacks of
using -999 to determine "end of data" in text streams...
An implicit cursor will *ALWAYS* raise a NO_DATA_FOUND exception.
You need to trap the NO_DATA_FOUND exception.
Simply enclose the implict cursor in it's own begin end block, trap
the exception and you are done. (Apart from reading the documentation
more closely, that is)
Sybrand Bakker, Senior Oracle DBA
To reply remove -verwijderdit from my e-mail address
Thanks! I had wondered why someone would nest a begin/exception/end block.
I always thought it was just to make the code easier to read. Now it makes
sense!

I see what you mean about always raising a no_data_found expression; I tried
using select with a group function on an empty test table- but the function
returned null, so SQL%NOTFOUND was false.

But why would the Oracle doc say that "%NOTFOUND yields TRUE if an INSERT,
UPDATE, or DELETE statement affected no rows, or a SELECT INTO statement
returned no rows." ? This is present in my Oracle 7 docs (actual paper
book!) from March 1995, A19486-2, PL/SQL release 2.2, Oracle 7.3, page 4-33.
I checked my Oracle 8i docs, and found it on page 5-39, Oracle 8i PL/SQL
Users Guide/Reference Dec 1999, A77069-01, a77069.pdf. I -even- went to the
Oracle 9.2 docs,
http://download-east.oracle.com/docs/cd/B10501_01/appdev.920/a96624.pdf ,
page 6-39 (Acrobat page 251).

Is that a documentation error for the select statement? Or, am I reading it
wrong? I went ahead and tested the DML ops, and %NOTFOUND works for them,
just not for a select statement. I guess I should send Oracle an e-mail...

Thanks,

-Thomas

Loading...