7 錯(cuò)誤消息與異常處理
7.1 異常的介紹
(1) 處理異常分為三個(gè)步驟:
A 聲明異常
B 引發(fā)異常
C 處理異常
(2) 異常的特征
A 錯(cuò)誤類型: ORA-xxxxx 運(yùn)行時(shí)錯(cuò)誤
PLS-xxxxx 編譯錯(cuò)誤
B 錯(cuò)誤代碼:xxxxx
C 錯(cuò)誤的文本描述
案例1:編譯錯(cuò)誤的案例PLS
SQL> create or replace procedure p1 is
2 begin
3 null;
4 end;
5 /
Procedure created.
SQL> create or replace procedure p1 is
2 begin
3 null --特意不寫分號(hào)
4 end;
5 /
Warning: Procedure created with compilation errors. --出現(xiàn)警告
SQL> show error --查看錯(cuò)誤消息
Errors for PROCEDURE P1:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/1 PLS-00103: Encountered the symbol "END" when expecting one of the
following:
;
The symbol ";" was substituted for "END" to continue.
案例2:運(yùn)行時(shí)錯(cuò)誤 -- 在編譯的時(shí)候沒有錯(cuò)誤,但是在執(zhí)行的時(shí)候發(fā)生錯(cuò)誤。
SQL> create or replace procedure p2 is
2 v_descr varchar2(20);
3 begin
4 select hrc_descr
5 into v_descr
6 from hrc_tab
7 where hrc_code=8;
8 dbms_output.put_line(to_char(v_descr));
9 end;
10 /
Procedure created.
SQL> exec p2; --運(yùn)行一個(gè)存儲(chǔ)過程
BEGIN p2; END;
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at "PLSQL.P2", line 4
ORA-06512: at line 1
總結(jié):
A PLSQL錯(cuò)誤 -- 編譯錯(cuò)誤,在執(zhí)行之前就已經(jīng)報(bào)錯(cuò),需要檢查程序,修改程序,debug
B ORA錯(cuò)誤 -- 運(yùn)行時(shí)錯(cuò)誤,出現(xiàn)這種錯(cuò)誤的時(shí)候需要手工處理,可以采用第三方軟件的單步調(diào)試方式處理
(2) 異常處理中的聲明,分為三個(gè)部分
A exception聲明,在聲明自己定義異常的時(shí)候需要用到這個(gè)方法。
B raise語(yǔ)句:顯示地引發(fā)異常
C pragma excetption_init 這個(gè)指令可以將oracle錯(cuò)誤和自己定義異常關(guān)聯(lián)起來
函數(shù)(需要定義變量來接收)
sqlcode -- 返回錯(cuò)誤的代碼號(hào),如果沒有錯(cuò)誤就返回0,可以根據(jù)sqlcode返回的值查詢官方文檔,獲得更詳細(xì)的錯(cuò)誤描述
sqlerrm -- 返回錯(cuò)誤的文本描述,如果沒有錯(cuò)誤返回normal或者successful completion,也就是官方文檔定義的錯(cuò)誤
(3) 異常處理的常見案例
declare
v_descr varchar2(20);
begin
select hrc_descr
into v_descr
from hrc_tab
where hrc_code=8;
dbms_output.put_line(v_descr);
exception when no_data_found then --異常的名稱
dbms_output.put_line('not exists');
end;
no_data_found --oracle預(yù)定義好的異常的名稱,oracle官方文檔上有每個(gè)異常名稱描述和引發(fā)的場(chǎng)景介紹
《PL/SQL User's Guide and Reference》pdf版本中第264頁(yè)
sqlcode與sqlerrm兩個(gè)函數(shù)的使用
declare
v_descr varchar2(20);
v_sqlcode number;
v_sqlerrm varchar2(200);
begin
select hrc_descr
into v_descr
from hrc_tab
where hrc_code=8;
dbms_output.put_line(v_descr);
exception when no_data_found then
v_sqlcode:=sqlcode;
v_sqlerrm:=sqlerrm;
dbms_output.put_line('not exists');
dbms_output.put_line('ERR: an error with info :'||to_char(v_sqlcode));
dbms_output.put_line(v_sqlerrm);
end;
輸出:
not exists
ERR: an error with info :100 --100是錯(cuò)誤的代碼號(hào),其他的錯(cuò)誤sqlcode都是ora-后面的號(hào)碼,這個(gè)異常特殊
ORA-01403: no data found --錯(cuò)誤的描述
對(duì)程序的異常進(jìn)行處理,讓程序不會(huì)在發(fā)生異常
declare
v_descr varchar2(20);
v_sqlcode number;
v_sqlerrm varchar2(200);
begin
select hrc_descr
into v_descr
asdfasdg from hrc_tab
where hrc_code=8;
dbms_output.put_line(v_descr);
exception when no_data_found then
v_sqlcode:=sqlcode;
v_sqlerrm:=sqlerrm;
dbms_output.put_line('not exists');
dbms_output.put_line('ERR: an error with info :'||to_char(v_sqlcode));
dbms_output.put_line(v_sqlerrm);
insert into hrc_tab values(8,'asdfasdg');
commit;
end;
第一次運(yùn)行
輸出:
not exists
ERR: an error with info :100
ORA-01403: no data found
再一次運(yùn)行
輸出:
asdfasdg
(4)PLSQL異常的功能性分類
A 預(yù)定義的異常 oracle自己預(yù)先定義好的
B 用戶自定義的異常
用戶自定義的異常
declare
site_s_undefined_for_org exception;
v_cnt number;
begin
select count(*) into v_cnt from org_site_tab where org_id=1007; --本身查詢是沒問題的
if v_cnt=0 then --只有在v_cnt值為0的時(shí)候引發(fā)異常
raise site_s_undefined_for_org;
end if;
exception when site_s_undefined_for_org then
dbms_output.put_line('empty table!');
when others then
dbms_output.put_line('ERR: an error with info :'||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
--自己定義異常,自己拋出異常,自己處理異常
系統(tǒng)預(yù)定義的異常
DUP_VAL_ON_INDEX --唯一性約束上有列值的重復(fù)沖突
declare
site_s_undefined_for_org exception;
v_cnt number;
begin
select count(*) into v_cnt from org_site_tab where org_id=1007; --本身查詢是沒問題的
insert into hrc_tab values(8,'asfdadsagsa');--這里出現(xiàn)異常,程序就進(jìn)入異常處理部分,后面不再執(zhí)行
commit;
if v_cnt=0 then --只有在v_cnt值為0的時(shí)候引發(fā)異常
raise site_s_undefined_for_org;
end if;
exception when site_s_undefined_for_org then
dbms_output.put_line('empty table!');
when DUP_VAL_ON_INDEX then
dbms_output.put_line('value repeat!');
when others then
dbms_output.put_line('ERR: an error with info :'||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
輸出:value repeat!
(3) pragma exception_init 指令
這個(gè)指令就是把oracle的錯(cuò)誤還有用戶自定義異常關(guān)聯(lián)起來
[oracle@test ~]$ oerr ora 02290 --知道錯(cuò)誤號(hào),可以使用該命令查看詳細(xì)錯(cuò)誤
02290, 00000, "check constraint (%s.%s) violated"
// *Cause: The values being inserted do not satisfy the named check
// constraint.
// *Action: do not insert values that violate the constraint.
select * from user_constraints where table_name='ORG_LEVEL';
SQL> conn plsql/plsql
Connected.
SQL> insert into org_level values(1001,'P');
insert into org_level values(1001,'P')
*
ERROR at line 1:
ORA-02290: check constraint (PLSQL.ORG_LEVEL_CK) violated
declare
invalid_org_level exception;
pragma exception_init(invalid_org_level,-2290); --關(guān)聯(lián)以后,就不需要raise引發(fā)異常
begin
create table exception_monitor(
excep_tab_name varchar2(30),
excep_key varchar2(50),
excep_program varchar2(30),
excep_name varchar2(30),
excep_code number,
excep_txt varchar2(200),
excep_date date
);
insert into org_level values(1001,'P');
commit;
exception when invalid_org_level then
dbms_output.put_line('ERR:an error with info :'||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
when others then
dbms_output.put_line('ERR:an error with info :'||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
可以讓程序自己拋出
begin
insert into org_level values(1001,'P');
commit;
exception
when others then
dbms_output.put_line('ERR:an error with info :'||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
##########################################################################################
成都創(chuàng)新互聯(lián)長(zhǎng)期為千余家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為阿巴嘎企業(yè)提供專業(yè)的網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì),阿巴嘎網(wǎng)站改版等技術(shù)服務(wù)。擁有10多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
7.2 異常監(jiān)控表
(1) 創(chuàng)建一個(gè)異常監(jiān)控表:exception_monitor
字段
發(fā)生異常的表的名字: excep_tab_name
發(fā)生異常的行的主鍵: excep_key
發(fā)生異常的程序的名稱: excep_program,如果是匿名塊就置為null
異常的名稱: excep_name 如果沒有定義就寫'others'
異常的sqlcode: excep_code
異常的文本描述: excep_txt
發(fā)生異常的時(shí)間: excep_date
以后編寫程序的時(shí)候都要編寫異常處理部分,獲取到上面這些信息,插入這個(gè)表
創(chuàng)建異常監(jiān)控表:
create table exception_monitor(
excep_tab_name varchar2(30),
excep_key varchar2(50),
excep_program varchar2(30),
excep_name varchar2(30),
excep_code number,
excep_txt varchar2(200),
excep_date date
);
改寫上面的例子:
declare
invalid_org_level exception;
pragma exception_init(invalid_org_level,-2290);
v_sqlcode number;
v_sqlerrm varchar2(200);
begin
insert into org_level values(1001,'P');
commit;
exception when invalid_org_level then
v_sqlcode:=sqlcode;
v_sqlerrm:=sqlerrm;
insert into exception_monitor values('ORG_LEVEL','1001',null,upper('invalid_org_level'),v_sqlcode,v_sqlerrm,sysdate);
commit;
when others then
v_sqlcode:=sqlcode;
v_sqlerrm:=sqlerrm;
insert into exception_monitor values('ORG_LEVEL','1001',null,upper('others'),v_sqlcode,v_sqlerrm,sysdate);
commit;
end;
練習(xí)7:將練習(xí)6那個(gè)程序修改它的異常處理部分,將錯(cuò)誤捕獲到監(jiān)控表
錯(cuò)誤號(hào)的20000~21299是錯(cuò)誤號(hào)的空缺范圍,這個(gè)范圍用來自定義錯(cuò)誤,用內(nèi)置的函數(shù)來引發(fā)這個(gè)錯(cuò)誤。
declare
site_s_undefined_fo_org exception;
pragma exception_init(site_s_undefined_fo_org,-20001);
v_cnt number;
begin
select count(1) into v_cnt from org_site_tab where org_id=1007;
if v_cnt=0 then
raise_application_error(-20001,'this table rows is empty!');
end if;
exception when site_s_undefined_fo_org then
dbms_output.put_line(sqlerrm);
when others then
dbms_output.put_line('ERR : an error with info :'||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
不關(guān)聯(lián)異常的名稱也可以:
declare
v_cnt number;
begin
select count(1) into v_cnt from org_site_tab where org_id=1007;
if v_cnt=0 then
raise_application_error(-20001,'this table rows is empty!');
end if;
exception
when others then
dbms_output.put_line('ERR : an error with info :'||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
##########################################################################################
7.3 在聲明部分引發(fā)的異常的處理
注意:異常需要在begin 和 exception 之間才能捕獲到的
declare
v_cnt number(2):=100;
begin
null;
exception when others then
dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
改寫:
begin
declare
v_cnt number(2):=100;
begin
null;
exception when others then
dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
exception when others then
dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
解決方法:將原來的代碼塊嵌套在一個(gè)begin和exception之間即可捕獲到
注意:
A 程序是從begin開始執(zhí)行的,declare部分不是程序執(zhí)行的部分
B 異常捕獲的區(qū)間是begin到exception之間的代碼
7.5 在異常部分引發(fā)異常的處理
declare
condition boolean:=true;
excep1 exception;
excep2 exception;
begin
if condition then
raise excep1;
end if;
exception when excep1 then
raise excep2;
end;
改寫:
declare
condition boolean:=true;
excep1 exception;
excep2 exception;
begin
if condition then
raise excep1;
end if;
exception when excep1 then
begin
raise excep2;
exception when excep2 then
dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
end;
或者
declare
condition boolean:=true;
excep1 exception;
excep2 exception;
begin
begin
if condition then
raise excep1;
end if;
exception when excep1 then
raise excep2;
end;
exception when excep2 then
dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
7.6 一個(gè)異??梢员欢啻我l(fā)
declare
condition boolean:=true;
excep1 exception;
begin
begin
if condition then
raise excep1;
end if;
exception when excep1 then
raise excep1;
end;
exception when excep1 then
dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
dbms_output.put_line(sqlerrm);
end;
新聞名稱:plsql的錯(cuò)誤信息與異常處理
文章路徑:http://jinyejixie.com/article0/pppdio.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站改版、網(wǎng)站維護(hù)、品牌網(wǎng)站設(shè)計(jì)、域名注冊(cè)、手機(jī)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)