2010-06-28 51 views

回答

5

每個塊都可以有一個異常處理程序。例如:

DECLARE 
    /* declare your variables */ 
BEGIN 
    /*Here is your code */ 
EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
     /* HAndle an error that gets raised when a query returns nothing */ 
    WHEN TOO_MANY_ROWS THEN 
     /* HAndle the situation when too much data is returned such as with a select-into */ 
    WHEN OTHERS THEN 
     /* Handle everything else*/ 
END; 

這個鏈接會告訴你更多:http://download.oracle.com/docs/cd/B13789_01/appdev.101/b10807/07_errs.htm

該鏈接會告訴你如何創建自己的異常的名字比我更詳細,還有例子。

總是讓我失望的一件事是,如果你有一個函數,並且你沒有在異常處理程序中返回一個值,則會在調用函數中拋出一個異常。沒什麼大不了的,但我似乎總是忘記那個。

+2

如果在較低塊中未捕獲到異常,它將傳播到較高級別塊(最終傳播到客戶端)。舊規則適用 - 永遠不要檢查你不知道如何處理的錯誤情況。讓它流起來。一個更高級別的程序塊會捕獲它,否則呼叫將失敗,客戶端應用程序(或用戶)將處理它。 – 2010-06-28 23:15:20

3

其他答案中引用的Oracle文章非常值得一讀。

要拋出一些額外的東西 - 捕獲PL/SQL異常會丟失錯誤堆棧 - 即關於確切哪一行引發異常的信息。

這可能會使調試包含多個可能引發相同異常的代碼塊(即,如果您有多個可能返回NO_DATA_FOUND的SQL語句)很難調試。這裏的一個選擇是將完整的錯誤堆棧記錄爲異常處理程序的一部分。

EXCEPTION 
    WHEN TOO_MANY_ROWS THEN 
     myLogger('Some useful information',DBMS_UTILITY.FORMAT_ERROR_STACK); 
END; 

如果你確實需要捕獲異常,讓您的異常處理的地方儘量要趕上點,只有使用的時候在不得已的情況等。

你也可以做某些事情,並重新提出同樣的異常'

EXCEPTION 
    WHEN TOO_MANY_ROWS THEN 
     closeSmtpConnection; 
     RAISE; 
END; 

其中最實用的功能就是能夠名稱和追趕的Oracle SQL內部例外。

DECLARE 
    recompile_failed  EXCEPTION; 
    PRAGMA EXCEPTION_INIT (recompile_failed,-24344); 
BEGIN 
    . . . . . . 
EXCEPTION 
    WHEN recompile_failed THEN 
     emailErrors(pObjectType,pObjectName); 
END; 

的另一面來這是爲了提高用戶定義的「SQL」例外

RAISE_APPLICATION_ERROR(-20001,'my text') 

這是傳播用戶定義的文本來調用應用程序的唯一途徑的能力,如用戶自定義的PL/sql異常不會跨越'範圍'邊界。

不幸的是,儘管文檔中提到範圍-20000到-20999可用於用戶定義的異常,但某些Oracle擴展軟件包使用這些串行,因此您不能僅依靠串行來確定調用中的錯誤語言。

(大多數人往往包裹RAISE_APPLICATION_ERROR在其他代碼也記錄錯誤,並經常推導從表中的錯誤文本)

一招,我發現有用的是創建具有「狀態包'包體中的變量,以及簡單的setter和getter函數。與數據庫更新不同,包中的信息不會因錯誤而回滾。

在發生錯誤時,在包中設置信息,然後使用調用語言中的getter檢索它,以構造「本機」異常。

至於用戶定義的pl/sql異常 - 這些可以在本地代碼中使用,但在很多情況下可以通過使用不同的控制結構來避免它們(即避免使用它們作爲替代GOTO)。

在包頭上創建全局異常來指定包可能返回的異常似乎是一個好主意,但最終的結果是您的調用代碼最終必須處理每個可能在任何可能出現的異常的底層軟件包。

在過去我一直走下這條路線,現在我會推薦它 - 使包自成體系,並使用RAISE_APPLICATION_ERROR或將錯誤作爲文本傳回。