2013-05-15 58 views
1

我在子程序中引发异常,我期待看到调用函数暂停执行。然而,调用函数继续处理,好像什么也没有发生,我不明白为什么。函数在子程序中出现异常后恢复执行

我的功能看起来是这样的:

FUNCTION getFooCursor (i_blah IN VARCHAR) 
    RETURN t_ref_cursor 
IS 
    v_sum_variable NUMBER; 
BEGIN 
    --lookup number 
    v_sum_variable := getNumber (i_blah); 

    --call function that raises NO_DATA_FOUND exception 
    doRaiseException(); 

    --the exception handler is only supposed to catch for this block 
    BEGIN 
     --do stuff and end up with a cursor 
     RETURN barCursor(v_sum_variable); 
    EXCEPTION 
     WHEN OTHERS THEN 
      --set some variables 
    END 
END; 

比方说doRaiseException()看起来是这样的:

PROCEDURE doRaiseException() 
IS 
BEGIN 
    RAISE NO_DATA_FOUND; 
END; 

当调试蟾蜍这个功能,它帮忙,告诉我,NO_DATA_FOUND例外是上调。然后,它立即执行下一行(调用barCursor())并且该函数结束,就好像没有任何错误发生一样。

我曾尝试直接与RAISE NO_DATA_FOUND;更换doRaiseException();用于测试目的(它实际上还不止这些),这站内getFooCursor()执行但无论SQL完全再次调用它忽略了异常。

这是PL/SQL中异常工作的方式吗?他们不像他们在Java或C#中那样冒泡吗?也许我错过了一些关于Oracle中异常的关键。我如何得到一个异常来冒充主机?


这里是我的Oracle版本(从V $版本返回):

Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi 
PL/SQL Release 10.2.0.5.0 - Production       
CORE 10.2.0.5.0 Production          
TNS for HPUX: Version 10.2.0.5.0 - Production     
NLSRTL Version 10.2.0.5.0 - Production 
+0

你确定你的第一个功能看起来完全一样吗?例外情况按照您的设想工作并“冒泡”,所以您必须在某处捕捉它。 – Ben

+0

@Ben:我在我的示例中添加了一些信息,在阅读您的评论后突然显得更加相关。回想起来显而易见...... – Stephan

回答

2

你对异常的理解是正确的。但是,这是异常工作的一个显着例外:NO_DATA_FOUND在SQL上下文中被默默忽略。这是一个“功能”,因为这是Oracle告诉其他进程没有更多数据要读取的方式。

对于自定义异常,您可能需要捕获NO_DATA_FOUND并将其作为不同的异常引发。这通常是处理异常的可怕方法,但这里没有好的选择。

SQL> create or replace function function1 return number is 
    2 begin 
    3  raise no_data_found; 
    4  return 1; 
    5 end; 
    6/

Function created. 

SQL> select function1 from dual; 

FUNCTION1 
---------- 


1 row selected. 

SQL> create or replace function function2 return number is 
    2 begin 
    3  raise no_data_found; 
    4  return 1; 
    5  exception when no_data_found then 
    6    raise_application_error(-20000, 'NO_DATA_FOUND raised'); 
    7 end; 
    8/

Function created. 

SQL> select function2 from dual; 
select function2 from dual 
     * 
ERROR at line 1: 
ORA-20000: NO_DATA_FOUND raised 
ORA-06512: at "JHELLER.FUNCTION2", line 6 
1

例外工作,你想和“冒泡”,所以你必须在某处捕获它。

这就是发生了什么......你正在捕捉每个的例外,这不是最佳做法。如果您自己定义一个,则只能确保您只有catch a specific exception。但是,这似乎并不是你想要在这里做的。您只想重新提出一个单个的异常。

所以,你可以define a custom exception in a separate package,提高在你的子计划,然后做这样的事情在你调用块:

begin 
    RaiseException; 

exception 
    when my_exception_package.my_exception then 
     raise; 
    when others then 
     DoSomethingElse; 
end; 

要提高再这样,你捕捉到的异常重新加注他们。如果异常情况不同,则继续当前的程序流程。

相关问题