PL/SQL異常分為預定義異常和用戶自定義異常:
1.預定義異常
(1)ZERO_DIVIDE異常。
DECLARE
v_number number(2):=10;
v_zero number(2):=0;
v_result number(5);
BEGIN
v_result:=v_number/v_zero;/*用v_number除以v_zero,即10除以0,從而產生除零錯誤*/
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('ZERO_DIVIDE');
END;
常見的PL/SQL系統預定義異常
no_data_found:如果一個select語句沒有查詢出任何結果集,會引發該異常
too_many_rows:使用者定義的遊標每次只能接收一行資料,但是查詢出的結果集如果是多行,會引發該異常
dup_val_on_index:索引中已有索引值,如果還要建立索引值給該索引會引發該異常
value_error:指定的變數長度小於從資料庫表中取回資料長度會引發該異常
case_not_found:在case語句中發現不匹配的語句會引發該異常
--轉換錯誤處理
DECLARE
v_number number(5);
v_result char(5):='2w';
BEGIN
v_number:=to_number(v_result);
EXCEPTION
WHEN VALUE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('CONVERT TYPE ERROR');
END;
如果當前數據庫中有一張XS(學生情況表)
XH XM ZYM XB CSSJ ZXF BZ
------ -------- ---------- -- ----------- --- --------------------------------------------------------------------------------
061101 王林 計算機 男 1986/2/10 50
061102 程明 計算機 男 1987/2/1 50
061103 王燕 計算機 女 1985/10/6 50
061104 韋嚴平 計算機 男 1986/8/26 50
061106 李方方 計算機 男 1986/11/20 50
061107 李明 計算機 男 1986/5/1 54 提前修完《數據結構》,並獲學分
061108 林一帆 計算機 男 1985/8/5 52 已提前修完一門課
061109 張強民 計算機 男 1984/8/11 50
061110 張蔚 計算機 女 1987/7/22 50 三好學生
061111 趙琳 計算機 女 1986/3/18 50
061113 嚴紅 計算機 女 1985/8/11 48 有一門功課不及格
061201 王敏 通訊工程 男 1984/6/10 42
061202 王林 通訊工程 男 1985/1/29 40 有一門功課不及格
061203 王玉民 通訊工程 男 1986/3/26 42
061204 馬琳琳 通訊工程 女 1984/2/10 42
061206 李計 通訊工程 女 1985/9/20 42
061210 李紅慶 通訊工程 女 1985/5/1 44 已提前修完一門課,並獲得學分
061216 孫祥欣 通訊工程 女 1984/3/9 42
061218 孫研 通訊工程 男 1986/10/9 42
061220 吳薇華 通訊工程 女 1986/3/18 42
061221 劉燕敏 通訊工程 女 1985/11/12 42
061241 羅林林 通訊工程 女 1986/1/30 50 轉專業學習
下面的兩個例子都是用來上面的表
--聯合的錯誤處理
DECLARE
v_result xs.xm%TYPE;
BEGIN
SELECT xm INTO v_result
FROM xs
WHERE xm='王林';
DBMS_OUTPUT.PUT_LINE('The student name is '||v_result);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('There has TOO_MANY_ROWS ERROR');
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('There has NO_DATA_FOUND ERROR');
END;
(2)自定義異常的例子
--自定義異常
DECLARE
e_overnumber EXCEPTION;
v_xs_number number(9);
v_max_xs_number number(9):=500;
BEGIN
SELECT COUNT(*) INTO v_xs_number
FROM xs;
IF v_max_xs_number<v_xs_number then
RAISE e_overnumber;
ELSE
DBMS_OUTPUT.PUT_LINE('沒有超過最大學生總數');
END IF;
EXCEPTION
WHEN e_overnumber then
DBMS_OUTPUT.PUT_LINE('CURREN XS NUMBER IS: '||v_xs_number||
' max allowed is: '||v_max_xs_number);
END;
使用others異常
--使用others異常
DECLARE
v_result number;
BEGIN
SELECT xm INTO v_result
FROM xs where xh='010010';
DBMS_OUTPUT.PUT_LINE('The student name is '||v_result);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('There has TOO_MANY_ROWS ERROR');
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('There has NO_DATA_FOUND ERROR');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('UNKNOW ERROR');
END;