2013-05-15 108 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; 

要提高再這樣,你捕捉到的異常重新加註他們。如果異常情況不同,則繼續當前的程序流程。

相關問題