PL/SQL學習(五)異常處理

原文參考:http://plsql-tutorial.com/

組成:
1) 異常類型
2) 錯誤碼
3) 錯誤信息
 
代碼結構:
DECLARE
Declaration section
BEGIN
Exception section
EXCEPTION
WHEN ex_name1 THEN
-Error handling statements
WHEN ex_name2 THEN
-Error handling statements
WHEN Others THEN
-Error handling statements
END;
嵌套的PL/SQL塊裏若是有異常拋出,且沒有進行異常處理時,
異常會交給最近的上層PL/SQL塊進行處理,若是上層塊中仍是
沒有進行處理,程序將在異常發生時退出。
 
異常類型:
a) 系統異常
 
異常名稱 發生緣由 錯誤碼
CURSOR_ALREADY_OPEN 打開一個已經打開的遊標 ORA-06511
INVALID_CURSOR 錯誤的遊標操做,如關閉未打開遊標或者從未打開遊標裏取數據。 ORA-01001
NO_DATA_FOUND SELECT...INTO語句沒能取到數據 ORA-01403
TOO_MANY_ROWS SELECT or fetch超過一行數據到變量或者記錄裏 ORA-01422
ZERO_DIVIDE 除0操做 ORA-01476
例子:
BEGIN
取數據操做
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line ('A SELECT...INTO did not return any row.');
END;
 
b) 未命名系統異常
 
兩種使用方式:
1.使用WHEN OTHERS異常處理器
2.將錯誤碼關聯到一個名字來將未命名系統異常當作已命名的使用
 
格式:
DECLARE
exception_name EXCEPTION;
PRAGMA
EXCEPTION_INIT (exception_name, Err_code);
BEGIN
Execution section
EXCEPTION
WHEN exception_name THEN
handle the exception
END;
(注:PRAGMA EXCEPTION_INIT的做用是將一個預先定義的Oracle錯誤碼
關聯到用戶定義的異常名
 
例子(未刪除子表中記錄的狀況下刪除父表中的記錄):
DECLARE
Child_rec_exception EXCEPTION;
PRAGMA
EXCEPTION_INIT (Child_rec_exception, -2292);
BEGIN
Delete FROM product where product_id= 104;
EXCEPTION
WHEN Child_rec_exception
THEN Dbms_output.put_line('Child records are present for this product_id.');
END;
/
c) 用戶自定義異常
例子(訂單數量超過20時報異常):
DECLARE
huge_quantity EXCEPTION;
CURSOR product_quantity is
SELECT p.product_name as name, sum(o.total_units) as units
FROM order_items o, product p
WHERE o.product_id = p.product_id;
quantity order_items.total_units%type;
up_limit CONSTANT order_items.total_units%type := 20;
message VARCHAR2(50);
BEGIN
FOR product_rec in product_quantity LOOP
quantity := product_rec.units;
IF quantity > up_limit THEN
message := 'The number of units of product ' || product_rec.name ||
' is more than 20. Special discounts should be provided.
Rest of the records are skipped. '
RAISE huge_quantity;
ELSIF quantity < up_limit THEN
message := 'The number of unit is below the discount limit.';
END IF;
dbms_output.put_line (message);
END LOOP;
EXCEPTION
WHEN huge_quantity THEN
dbms_output.put_line (message);
END;
/
 
RAISE_APPLICATION_ERROR ( )
這是一個Oracle內嵌的存儲過程,用來錯誤碼範圍在-20000到-20999之間用戶自定義異常。
當使用這個時,全部未提交的事務都將自動回滾。
這個操做只觸發操做異常,而不對異常進行處理。
 
RAISE_APPLICATION_ERROR()做用
a) 爲用戶自定義異常綁定一個錯誤碼
b) 使得用戶自定義異常看起來跟Oracle錯誤同樣
 
語法格式:
RAISE_APPLICATION_ERROR (error_number, error_message);
 
例子:
DECLARE
huge_quantity EXCEPTION;
CURSOR product_quantity is
SELECT p.product_name as name, sum(o.total_units) as units
FROM order_items o, product p
WHERE o.product_id = p.product_id;
quantity order_items.total_units%type;
up_limit CONSTANT order_items.total_units%type := 20;
message VARCHAR2(50);
BEGIN
FOR product_rec in product_quantity LOOP
quantity := product_rec.units;
IF quantity > up_limit THEN
RAISE huge_quantity;
ELSIF quantity < up_limit THEN
message:= 'The number of unit is below the discount limit.';
END IF;
Dbms_output.put_line (message);
END LOOP;
EXCEPTION
WHEN huge_quantity THEN
raise_application_error(-2100, 'The number of unit is above the discount limit.');
END;
/
 
相關文章
相關標籤/搜索