2016-05-17 57 views
2

我有一個相當簡單的問題:在包級別可以進行異常處理嗎?如果是的話,如何實施呢?PL/SQL包級別異常處理

我的程序包中包含程序和函數,例如,我想說的是,我想在我的所有過程和函數中做同樣的事情。

所以我的問題是:我可以寫

WHEN NO_DATA_FOUND THEN 

了一次,並且使用NO_DATA_FOUND例外同樣的思路在我所有的過程/函數,或做我必須寫在每一個過程,異常處理程序/功能。

回答

4

不,這是不可能的。我期望這不在語言中,因爲它與正常和預期的異常處理程序的使用不一致。

我應用的一般經驗法則是:「如果您沒有特定的東西並且對異常做出有用的迴應,請不要理解它」。

如果NO_DATA_FOUND預期和確定在特定情況下,你可以忽視它和/或承擔數據的默認值,然後你想趕上並處理(和封裝級處理器將不會幫助,因爲你的處理將取決於情況)。在所有其他情況下,您不希望發現NO_DATA_FOUND - 這代表了一個真正的例外:應該不會發生的事情,超出了您的設計假設。讓這些人傳播到最高層,他們可以登錄他們和/或將他們報告給客戶端。

但是,如果你解釋了你希望包級異常處理程序執行的操作,也許你會得到更好的答案。

+0

我同意你的說法,並且已經有很多原因,有很好的理由,爲變量賦值等等。包級別異常僅用於記錄目的,解釋起來很複雜,但我無法在更高級別上記錄異常,所以我必須在此包中執行此操作。感謝您的回答 – BeRightBack

5

不,您無法在包中的所有過程/函數中全局處理異常。

The exception handler documentation說:

異常處理程序處理引發異常。異常處理程序出現在匿名塊,子程序,觸發器和包的異常處理部分中。

這使得它聽起來像你一樣;但「包」參考有指create package body statement的初始化部分:

enter image description here

但是,這部分「初始化變量,並沒有任何其他的一次性設置步驟」,並且每個會話運行一次,當程序包中的函數或過程首次被調用時。它的異常處理程序不會執行其他操作。

如果你真的想要類似的行爲,那麼你可以把它放到它自己的(可能是私有的)過程中,並從每個過程/函數的異常處理程序調用它。這可能會節省一些打字的時間,但如果你想記錄錯誤,可能會掩蓋真正發生的事情。即使這會導致一些重複,可能會更簡單,更好地進行特定的異常處理。

4

程序包不是可執行對象,因此它不能處理程序包中的過程和函數的異常。您需要處理生成的異常。

每次出現特定的異常時,你確實想要做同樣的事情似乎有點不太可能。通常情況下,您希望異常處理程序儘可能接近產生錯誤的代碼,以便儘可能多地使用上下文。通常情況下,這意味着在一個過程中有多個異常處理程序,

PROCEDURE p1 
AS 
    ... 
BEGIN 
    BEGIN 
    SELECT col1 
     INTO l_var1 
     FROM some_table 
    WHERE <<something>> 
    EXCEPTION 
    WHEN no_data_found 
    THEN 
     l_var1 := null; 
    END; 

    <<do something>> 

    BEGIN 
    SELECT col2 
     INTO l_var2 
     FROM some_table2 
    WHERE <<something>> 
    EXCEPTION 
    WHEN no_data_found 
    THEN 
     raise_application_error(-20001, 'Error, cannot find a row in some_table2'); 
    END; 

    ... 
END;