2016-02-11 155 views
2

我在寫我的pl sql包。我有一個像PLSQL處理自定義異常

FUNCTION my_func(argument IN NUMBER) 
     RETURN NUMBER 
BEGIN 
    return some_package.somefunction(argument); 
END; 

我想處理異常的函數,如果

  1. some_package犯規存在被拋出。
  2. 某些功能不存在。

這些例外是什麼?它們是預定義的還是應該定義它們來處理?我不確定他們是否在預定義的列表中here

如何處理異常?

+0

你會如何處理函數不存在?讓我們不要往返回失敗的路徑0,並且每個其他數字都意味着成功,那樣會導致災難 – kevinsky

+3

如果被調用的函數不存在,那麼編譯時可能會出錯,而不是運行時錯誤來處理。 – Aleksej

+1

你不能。你在談論編譯錯誤而不是運行時錯誤。如果包不存在,則不能編譯您的函數。如果無法編譯,則無法執行。如果無法執行,則不能有捕獲錯誤的異常處理程序塊。我想如果你是一個受虐狂的人,你可以編寫你的代碼,這樣你就可以在任何地方使用動態SQL,這樣編譯錯誤就會變成運行時錯誤。但這是寫軟件的一種可怕的方式。處理每個錯誤通常是沒有意義的 - 處理你期望的錯誤並讓其餘的傳播。 –

回答

1

要回答您的一般問題,大多數Oracle錯誤不要已預先定義與它們相關聯的命名異常,只是您找到的幾十打。

但是,您可以創建自己的命名異常,他們這樣的關聯:

declare 
    table_or_view_does_not_exist exception; 
    pragma exception_init (table_or_view_does_not_exist, -942); 
    l_table_name varchar2(30) := 'XXX'; 
    l_count integer; 
begin 
    execute immediate 'select count(*) from ' || l_table_name into l_count; 
exception 
    when table_or_view_does_not_exist then 
     raise_application_error (-20001, 'No such table exists'); 
end; 
/

declare 
* 
ERROR at line 1: 
ORA-20001: No such table exists 
ORA-06512: at line 10 

你如何實際處理的例外是你。

您可以在包規範申報等異常,然後在其他代碼中使用它們:

when my_package.my_exception then... 

或者,你可以捕捉他們都在WHEN OTHERS,然後用sqlcode識別它們:

declare 
    l_table_name varchar2(30) := 'XXX'; 
    l_count integer; 
begin 
    execute immediate 'select count(*) from ' || l_table_name into l_count; 
exception 
    when others then 
     case sqlcode 
      when -942 then 
       raise_application_error (-20001, 'No such table exists'); 
      else 
       raise; 
     end case; 
end; 
+0

這段代碼處理每個可能的異常嗎? –

+0

絕對是! –

0

有一點可以肯定,當你創建函數「my_func」時,存在「some_package」和「some_package.somefunction」,否則你在創建時會出錯。

如果它們被移除(包或包中的函數),那麼「my_func」將自動失效,甚至無法執行它。

測試用例:

create or replace package some_package as 

function somefunction(a number) return number; 

end; 
/

create or replace package body some_package as 

function somefunction(a number) return number is 
begin 
    return 1; 
end; 

end; 
/

create or replace function my_func return number is 
begin 
    return some_package.somefunction(1); 
end; 
/

set serveroutput on size 2000 

begin 
    dbms_output.put_line(my_func()); 
end; 
/

drop package some_package; 

begin 
    dbms_output.put_line(my_func()); 
end; 
/

產量:創建

包。

已創建包體。

創建的函數。

PL/SQL過程已成功完成。

包丟失。

dbms_output.put_line(my_func()); *第2行的錯誤:ORA-06550:第2行,第24列:PLS-00905:對象DEMO。my_func,並將無效ORA-06550:2號線, 第3列:PL/SQL:語句被忽略

只有這樣,才能防止「my_func,並將」成爲無效是調用使用「執行立竿見影」,然後功能捕獲錯誤。

新的「my_func」看起來像這樣,永遠不會失效。

create or replace function my_func return number is 
    v_return  number; 
begin 
    execute immediate 'begin :r := some_package.somefunction(1); end;' using out v_return; 
    return v_return; 
exception 
    when others then 
    dbms_output.put_line(SQLERRM); 
    dbms_output.put_line('Package or function does not exists anymore'); 
    return -1; 
end; 
/

,並會產生這樣的結果:

Package created. 


Package body created. 


Function created. 

1 

PL/SQL procedure successfully completed. 


Package dropped. 

ORA-06550: line 1, column 13: 
PLS-00201: identifier 'SOME_PACKAGE.SOMEFUNCTION' 
must be declared 
ORA-06550: line 1, column 7: 
PL/SQL: Statement ignored 
Package or function does not exists anymore 
-1 

PL/SQL procedure successfully completed.