Thanks, I understood it
SeongHoon Park, June 14, 2007 - 10:24 pm UTC
I am using stored procedure mostly for executing a series of DMLs and using CALL or not is not a choice of me but application developers.
So I think that raising an explicit error instead of NO_DATA_FOUND can be a proper workaround for most of our cases.
SQL> create or replace function f_explicit return varchar2 is
l_v number;
begin
begin
select 1 into l_v from dual where 1=0;
exception
when NO_DATA_FOUND then
raise_application_error(-20001,'an explicit error');
end;
/* dmls */
end;
/
Thanks , Tom.
Bug with exceptions propagation in SQL Statement Executor
Sergey Trotsky, September 25, 2007 - 7:57 am UTC
Some of the exceptions are suppressed by SQL Statement Executor. The different exceptions lead to absolutely unpredictable results. Sometimes SQL Statement Executor treats the function return value as NULL, sometimes the rows with the unhandled exceptions magically disappear from the query results...
create or replace function Func1 return integer is
Res integer;
begin
-- raise ORA-01403: no data found
select SID into Res from V$MYSTAT where (ROWNUM=0);
return(Res);
end Func1;
/
create or replace function Func2 return integer is
Res integer;
begin
-- raise ORA-01422: exact fetch returns more then requested number of rows
select SID into Res from V$MYSTAT;
return(Res);
end Func2;
/
select ROWNUM, SID from V$SESSION where (SID=Func1)
/
select ROWNUM, Func1 from DUAL
/
select ROWNUM, SID from V$SESSION where (SID=Func2)
/
select ROWNUM, Func2 from DUAL
/
This is the script results:
Function created
Function created
ROWNUM SID
---------- ----------
ROWNUM FUNC1
---------- ----------
1
ROWNUM SID
---------- ----------
ROWNUM FUNC2
---------- ----------
There is no complete list of exceptions with unexpected behaviour. I did not find any mentions about this "feature" in documentation. This bug was gotten on Oracle 9.2 and can be reproduced on Oracle 10.2.
September 26, 2007 - 9:22 pm UTC
it is entirely the clients fault here - please consider what the client code probably looks like:
open cursor
loop
fetch
when no data found is raised... then let us exit
print output
SQL Statement Executor ignore ORA-01403 (no data found)
Sergey Trotsky, September 27, 2007 - 7:30 am UTC
Thanks! It is looks like a real client fault with ORA-01422 (Exact fetch returns more then requested number of rows). Exception was raised but the client does not display it.
However with ORA-01403 (no data found) the situation is still unclear. SQL Statement Executor returns the rows in spite on unhandled exceptions.
Are there any other exceptions that can be "handled" by SQL Statement Executor?
Where does it documented?
September 28, 2007 - 3:07 pm UTC
not sure what you mean in the last bit - not sure what "sql statement executor" is by your definition
Oracle SQL Engine vs Oracle PL/SQL Engine
Sergey Trotsky, October 01, 2007 - 11:49 am UTC
"SQL Statement Executor" = "Oracle SQL Engine"
create or replace function Func1 return integer is
Res integer;
begin
-- raise ORA-01403: no data found
select 1 into Res from DUAL where (0=1);
return(Res);
end Func1;
/
declare
Res integer;
begin
Res := Func1;
end;
/
select RowNum, Func1 from DUAL
/
Oracle PL/SQL Engine returns an exception. OK.
Oracle SQL Engine returns the row. There is no exception. It is a bug!
October 03, 2007 - 4:03 pm UTC
sql doesn't throw exceptions - sql can raise errors and no data found is not an error in sql, it is a state of being - no more data.
SQL called from PL/SQL also has this problem...
Devin R, October 15, 2008 - 2:41 pm UTC
Note that using PL/SQL as a "client" also causes this problem. For instance, assuming raise_no_data_found has been modified to return a VARCHAR2:
declare
p_dummy varchar2(200);
begin
select raise_no_data_found into p_dummy from dual;
dbms_output.put_line( 'No error.' );
if p_dummy is null then
dbms_output.put_line( 'Var is null.' );
end if;
exception
when others then
dbms_output.put_line( 'Error: ' || sqlerrm );
end;
The output will be:
No error.
Var is null.
In other words, Oracle's own PL/SQL engine, acting as a SQL
"client", will not throw an error in this case. This seems
somewhat counter-intuitive, considering a usual "empty"
call would throw the NO_DATA_FOUND error from the SELECT
line. Developers should probably be aware of this caveat
of calling functions via SQL within PL/SQL code.
October 17, 2008 - 7:04 pm UTC
I'll ask about that particular case, that doesn't look right.
counterintuitive
Duke Ganote, November 29, 2008 - 12:22 pm UTC
The 10gR2 note on NO_DATA_FOUND says "Because this exception is used internally by some SQL functions to signal completion, you should not rely on this exception being propagated if you raise it within a function that is called as part of a query."
I included this in my exception handler:
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20000,'NO_DATA:FATALITY (just ORA-01403 not guaranteed fatal)');
Mehmet Kaplan, April 15, 2009 - 2:35 pm UTC
Instead of using
call my_procedure();
Using
exec my_procedure();
or
begin
my_procedure;
end;
/
solves the problem in a quick manner.
But still the below example proves that all exceptions do not behave smilar so must be treated as a "bug".
create function raise_no_data_found return varchar2 is
begin
raise no_data_found;
return 'x';
end;
Function created
create function raise_too_many_rows return varchar2 is
begin
raise TOO_MANY_ROWS;
return 'x';
end;
Function created
select nvl(raise_no_data_found, 'aa')
from dual
NVL(RAISE_NO_DATA_FOUND,'AA')
--------------------------------------------------------------------------------
aa
1 row selected
select nvl(raise_TOO_MANY_ROWS, 'x')
from dual
0 rows selected