Oracle中的異常處理與自定義異常方式
一、什么是異常處理
程序因?yàn)閿?shù)據(jù)的原因或者入?yún)⒌脑?,?dǎo)致程序出錯(cuò),這個(gè)時(shí)候,為了面對(duì)這種不可避免的問(wèn)題,程序塊里面添加了異常處理,當(dāng)程序異常的時(shí)候,該怎么辦,可以在異常中定義。
二、異常的兩種分類(lèi)
(1) 系統(tǒng)預(yù)定義:Oracle 自動(dòng)拋出(如:'違反唯一性約束')
(2) 用戶自定義:編碼人員認(rèn)為的 '非正常情況' ( v_exp1 EXCEPTION)
其中 '用戶自定義' 的異常在 pl/sql 環(huán)境使用,需 '顯式拋出'。
三、常見(jiàn)的預(yù)定義異常
| 異常名稱(chēng) | 錯(cuò)誤代碼 | 說(shuō)明 |
|---|---|---|
| NO_DATA_FOUND | ORA-01403 | 查詢(xún)無(wú)結(jié)果 |
| TOO_MANY_ROWS | ORA-01422 | 查詢(xún)返回多行,而 INTO 只接收一行 |
| DUP_VAL_ON_INDEX | ORA-00001 | 違反唯一約束 |
| ZERO_DIVIDE | ORA-01476 | 除數(shù)為零 |
| INVALID_NUMBER | ORA-01722 | 字符串轉(zhuǎn)數(shù)字失敗 |
| TIMEOUT_ON_RESOURCE | ORA-00051 | 等待資源超時(shí) |
四、異常處理語(yǔ)法
EXCEPTION
WHEN [OTHERS] -- 異常場(chǎng)景
THEN -- 則做的事情五、異常常用的三種方案
RAISE 異常拋出 --程序不接著往下執(zhí)行 NULL 忽略異常 ROLLBACK 異?;貪L --程序出現(xiàn)異常則回滾 程序的相關(guān)操作(UPDATE/INERT/DELETE)
捕捉異常的關(guān)鍵字是 SQLERRM 它能夠得到 異常的詳細(xì)信息
六、使用RAISE_APPLICATION_ERROR創(chuàng)建自定義錯(cuò)誤碼
自定義異常參數(shù):使用RAISE_APPLICATION_ERROR拋出帶自定義錯(cuò)誤碼和消息的異常。
開(kāi)發(fā)者自定義的錯(cuò)誤碼,范圍為-20000至-20999:
DECLARE
v_salary NUMBER := 100000;
BEGIN
IF v_salary > 50000 THEN
RAISE_APPLICATION_ERROR(-20001, '工資超出上限'); -- 自定義錯(cuò)誤碼
END IF;
END;
七、異常練習(xí)
declare
v_num number := &input;
exp_date_range exception; -- 異常定義
begin
if v_num < 0 then
raise exp_date_range; -- 異常拋出
end if;
dbms_output.put_line(v_num);
exception
when exp_date_range then
dbms_output.put_line('數(shù)據(jù)范圍不能為負(fù)數(shù)!');
end;

捕捉異常信息:
示例:將EMP表的數(shù)據(jù)同步到EMP表(把EMP表的數(shù)據(jù)重復(fù)兩遍)
create or replace procedure p_16 is
begin
insert into emp
select * from emp;
commit;
exception
when others then
dbms_output.put_line(SQLERRM);
end;
BEGIN
p_16;
end;
示例:入?yún)T工編號(hào),打印對(duì)應(yīng)員工的姓名
程序出現(xiàn)異常之后,忽略使用null;當(dāng)出現(xiàn)異常的時(shí)候,讓程序跳出執(zhí)行 彈出一個(gè)報(bào)錯(cuò)的框 即拋出異常
create or replace procedure p_17(p_empno number) is
v_name varchar2(10);
begin
select ename into v_name from emp where empno = p_empno;
dbms_output.put_line(v_name);
exception
when others then
dbms_output.put_line(SQLERRM);
null;
raise; -- 彈出窗口
-- rollback;-- 也可以進(jìn)行回滾
-- 注意:raise語(yǔ)句會(huì)重新拋出當(dāng)前異常,導(dǎo)致后續(xù)的 rollback; 永遠(yuǎn)不會(huì)執(zhí)行
end;
BEGIN
p_17(p_empno=>1111);
end;
程序出現(xiàn)異常,則回滾
下面是一個(gè)匿名 PL/SQL 塊:
DECLARE
dept_no NUMBER(2) := 70;
BEGIN
--開(kāi)始事務(wù)
INSERT INTO dept VALUES (70, '市場(chǎng)部', '北京'); --插入部門(mén)記錄
INSERT INTO dept VALUES (70, '后勤部', '上海'); --插入相同編號(hào)的部門(mén)記錄
INSERT INTO emp --插入員工記錄
VALUES
(7997, '威爾', '銷(xiāo)售人員', NULL, TRUNC(SYSDATE), 5000, 300, 70);
--提交事務(wù)
COMMIT;
EXCEPTION
WHEN OTHERS THEN
--捕捉異常
DBMS_OUTPUT.PUT_LINE(SQLERRM); --顯示異常消息
ROLLBACK; --回滾異常
END;因?yàn)閐ept表的主鍵插入重復(fù),所以捕捉到異常,數(shù)據(jù)回滾,
插入emp表的語(yǔ)句在插入dept表之后,dept表未插入成功,emp表的語(yǔ)句不會(huì)跑,因此兩張表都插入失敗
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Oracle通過(guò)正則表達(dá)式分割字符串 REGEXP_SUBSTR的代碼詳解
這篇文章主要介紹了Oracle通過(guò)正則表達(dá)式分割字符串 REGEXP_SUBSTR的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05
Oracle連續(xù)相同數(shù)據(jù)的統(tǒng)計(jì)
今天小編就為大家分享一篇關(guān)于Oracle連續(xù)相同數(shù)據(jù)的統(tǒng)計(jì),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01
Oracle數(shù)據(jù)泵(expdp)導(dǎo)入導(dǎo)出數(shù)據(jù)的詳細(xì)步驟
這篇文章主要介紹了Oracle數(shù)據(jù)泵(expdp)導(dǎo)入導(dǎo)出數(shù)據(jù)的詳細(xì)步驟,文中詳細(xì)描述了源數(shù)據(jù)庫(kù)操作中的數(shù)據(jù)備份和目標(biāo)數(shù)據(jù)庫(kù)操作中的數(shù)據(jù)恢復(fù)過(guò)程,需要的朋友可以參考下2024-12-12
ORACLE DATAGUARD中手工處理日志v$archive_GAP的方法
從9i以后,oracle dataguard 備庫(kù)一般都不需要手工處理丟失的日志,F(xiàn)AL自動(dòng)會(huì)幫我們處理,本文主要通過(guò)個(gè)案例來(lái)講下手工處理丟失的日志的方法。2014-08-08
Oracle捕獲問(wèn)題SQL解決CPU過(guò)渡消耗
本文通過(guò)實(shí)際業(yè)務(wù)系統(tǒng)中調(diào)整的一個(gè)案例,試圖給出一個(gè)常見(jiàn)CPU消耗問(wèn)題的一個(gè)診斷方法.2007-03-03
Oracle數(shù)據(jù)庫(kù)安全策略分析(一)
Oracle數(shù)據(jù)庫(kù)安全策略分析(一)...2007-03-03
Oracle密碼過(guò)期如何取消密碼180天限制及密碼180天過(guò)期,賬號(hào)鎖住的問(wèn)題
這篇文章主要介紹了Oracle密碼過(guò)期如何取消密碼180天限制及密碼180天過(guò)期,賬號(hào)鎖住的問(wèn)題,需要的朋友可以參考下2018-12-12

