程式執行過程中出現錯誤情況被稱為在PL/SQL異常(Exception)。 PL/SQL支援在程式中使用異常區塊捕獲這樣的狀況並采取適當的動作應對錯誤情況。有兩種類型的異常:
- 系統定義的異常
- 使用者定義的異常
異常處理語法
一般異常處理的語法如下。在這裡可以列出下來很多,要處理異常。預設的異常將使用WHEN others THEN處理:
DECLARE
<declarations section> BEGIN <executable command(s)> EXCEPTION <exception handling goes here > WHEN exception1 THEN exception1-handling-statements WHEN exception2 THEN exception2-handling-statements WHEN exception3 THEN exception3-handling-statements ........ WHEN others THEN exception3-handling-statements END;
/
|
範例
DECLARE
c_id customers.id%type := 8; c_name customers.name%type; c_addr customers.address%type; BEGIN SELECT name, address INTO c_name, c_addr FROM customers WHERE id = c_id; DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name); DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr); EXCEPTION WHEN no_data_found THEN dbms_output.put_line('No such customer!'); WHEN others THEN dbms_output.put_line('Error!'); END; / |
結果如下:
No such customer!
PL/SQL procedure successfully completed. |
上述顯示一個客戶的ID給出的名字和地址。資料庫內沒有ID為8的客戶,因此程式運作時引發出異常NO_DATA_FOUND,交由EXCEPTION區塊處理。
引發異常
異常可以明確地提出由程式開發人員使用指令RAISE。以下是引發異常的簡單的語法:
DECLARE
exception_name EXCEPTION; BEGIN IF condition THEN RAISE exception_name; END IF; EXCEPTION WHEN exception_name THEN statement; END;
/
|
使用者自定義異常
PL/SQL允許根據程式的需要定義自己的異常。定義的異常必須宣告,然後明確地提出使用一個RAISE語法或程序DBMS_STANDARD.RAISE_APPLICATION_ERROR。
宣告一個異常的語法是:
DECLARE
my-exception EXCEPTION; |
範例:
下面的例子說明了這個概念。當使用者輸入了一個無效的ID,異常invalid_id引發。(範例table)
DECLARE
c_id customers.id%type := &cc_id; c_name customers.name%type; c_addr customers.address%type; -- user defined exception ex_invalid_id EXCEPTION; BEGIN IF c_id <= 0 THEN RAISE ex_invalid_id; ELSE SELECT name, address INTO c_name, c_addr FROM customers WHERE id = c_id; DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name); DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr); END IF; EXCEPTION WHEN ex_invalid_id THEN dbms_output.put_line('ID must be greater than zero!'); WHEN no_data_found THEN dbms_output.put_line('No such customer!'); WHEN others THEN dbms_output.put_line('Error!'); END; / |
結果如下:
Enter value for cc_id: -6 (let's enter a value -6)
old 2: c_id customers.id%type := &cc_id; new 2: c_id customers.id%type := -6; ID must be greater than zero! PL/SQL procedure successfully completed. |
預先定義異常
PL/SQL提供許多預先定義的異常,這是在被執行時的任何資料庫規則由序式引發。例如,預定義異常NO_DATA_FOUND時引發一個SELECT INTO語句回傳資料筆數。下表列出了一些重要的預先定義的異常:
Exception
|
Oracle Error
|
SQLCODE
|
描述
|
ACCESS_INTO_NULL
|
06530
|
-6530
|
當一個空物件會自動分配一個值引發此異常
|
CASE_NOT_FOUND
|
06592
|
-6592
|
當沒有任何選擇,在當選擇一個CASE語句的子句,並且沒有ELSE子句時被引發
|
COLLECTION_IS_NULL
|
06531
|
-6531
|
當程式試圖申請其他收集方法不是存在未初始化的嵌套表或VARRAY,或程序試圖值分配給未初始化的嵌套表或變長數組的元素時被引發
|
DUP_VAL_ON_INDEX
|
00001
|
-1
|
當重複值試圖被存儲在具有唯一索引的列時被引發
|
INVALID_CURSOR
|
01001
|
-1001
|
當嘗試以使這是不允許的,如關閉一個未打開的遊標的遊標操作時被引發
|
INVALID_NUMBER
|
01722
|
-1722
|
當一個字符的字符串轉換成一個數失敗,因為字符串不表示一個有效的數據被引發
|
LOGIN_DENIED
|
01017
|
-1017
|
當程序試圖登錄到資料庫使用無效的用戶名或密碼被引發
|
NO_DATA_FOUND
|
01403
|
+100
|
它被引發當一個SELECT INTO語句無任何行返回
|
NOT_LOGGED_ON
|
01012
|
-1012
|
在不連接到資料庫發出資料庫調用它被引發
|
PROGRAM_ERROR
|
06501
|
-6501
|
它被引發當PL/SQL有一個內部問題
|
ROWTYPE_MISMATCH
|
06504
|
-6504
|
當遊標取值有不兼容的數據類型的變量被引發
|
SELF_IS_NULL
|
30625
|
-30625
|
它被引發,當對象的成員方法被調用,但對象類型的實例沒有被初始化。
|
STORAGE_ERROR
|
06500
|
-6500
|
它被引發當PL/SQL記憶體不足或記憶體已損壞
|
TOO_MANY_ROWS
|
01422
|
-1422
|
它被引發當SELECT INTO語句回傳多筆資料
|
VALUE_ERROR
|
06502
|
-6502
|
當計算,轉換,截短,或大小約束錯誤時引發
|
ZERO_DIVIDE
|
01476
|
1476
|
它被引發當一個數試圖除以零。
|
沒有留言:
張貼留言