PLSQL學習(三) 異常處理
?
??? 任何一種編程語言中的異常處理部分都是比較重要的一部分,單獨學習一下。
?
?
一、異常的種類及基本用法:
?
1、預定義異常(總計21種,具體見文檔)
?
??? 使用方法:
??? BEGIN
?????
SELECT
...
?????
SELECT
...
?????
SELECT
...
??
??? ...
??? EXCEPTION
?
??? WHEN
NO_DATA_FOUND
THEN
...
?
??? 常用類型:
??? NO_DATA_FOUND??????
--ORA-01403--
未找到行
??? TOO_MANY_ROWS??????
--ORA-01422--SELECT INTO
語句返回多行數據
??? VALUE_ERROR????????
--ORA-06502--
類型轉換錯誤
??? ZERO_DIVIDE????????
--ORA-01476--
程序嘗試除以
0
?STORAGE_ERROR??????
--ORA-06500--PL/SQL
運行時內存溢出或內存不足
?
2、非預定義異常(EXCEPTION_INIT
)
?
??? 方法一:
??? 需要在declare中申明,申明后使用即與預定義異常相同
??? declare
??????e_deptno_remaining
exception
;
??????
PRAGMA
EXCEPTION_INIT
(e_deptno_remaining, -
2292
);
??? begin
??? ...
??? exception
??? when
e_deptno_remaining
then
??? dbms_output.put_line(
'
非預定義2292
'
);
??? when
others
then
??? dbms_output.put_line(
'others'
);
??? end
;
?
-2292必須是oracle自定義的錯誤號,前面加負號
如果需要自己設定,則必須在-20000——-20999之間
此方法無法定義異常信息。
?
??? 方法二:
??? 錯誤號與錯誤信息均可自己定義
??? 且無需在declare和exception中聲明
??? declare
????? i int := 5;
??? begin
?????if i=5then
?????raise_application_error (-20086/*-20000——-20999*/, '自定義錯誤信息');
?????endif;
??? end;
?
3、自定義異常(分為declare、raise、exception三部分)
?
??? 使用示例:
??? declare
????? i int := 3;
????? ex exception;
??? begin
????? if i <=2then
????? raise ex;
????? else dbms_output.put_line(i);?????????????????????????????
????? endif;
??? exception
????? when ex then
????? dbms_output.put_line('xxx');
??? end;
?
?
二、注意使用Others的異常類:
?
??? 在EXCEPTION中定義任何的異常后
??? 盡量都使用when others
??? 表示遭遇到除此之外的任何異常如何處理
?
??? EXCEPTION
????? WHEN exception_name1 THEN?? -- handler
??????? sequence_of_statements1
????? WHEN exception_name2 THEN?? -- another handler
??????? sequence_of_statements2
??????? ...
????? WHENOTHERSTHEN??????????? -- optional handler
??????? sequence_of_statements3
??? END;?
?
??? 另外,在EXCEPTION中可以使用OR鏈接??? WHEN over_limit OR under_limit OR VALUE_ERROR THEN
?
?
三、使用系統錯誤號和錯誤信息
?
??? 錯誤號----SQLCODE;
??? 錯誤信息--SQLERRM;
??? DECLARE
????? err_num?? NUMBER;
????? err_msg?? VARCHAR2(100);
??? BEGIN
????? ...
??? EXCEPTION
????? WHENOTHERSTHEN
??????? err_num??? := SQLCODE;
??????? err_msg??? := SUBSTR(SQLERRM, 1, 100);
??????? dbms_output.put_line(err_num || '---' || err_msg);
??? END;
?
?
四、異常傳播的規則
?
??? 首先,異常是會向他的外層進行傳遞的
??? 即如果在當前子塊中未定義異常處理,則會傳遞到外層的異常處理
??? 直到異常被捕獲或最終被拋棄
?
??? 注:聲明中的異常必定無法被當前塊捕獲
??? DECLARE
??? Abc number(3):='abc';
??? ...
??? BEGIN
??? ...
??? EXCEPTION
??? WHENOTHERSTHEN
??? ...
??? END;----即便使用others最終也無法捕獲
?
?
?