在 PL / SQL 中錯誤信息處理過程分為兩步: 引發(fā)錯誤和處理錯誤。編譯處誤是由 PL/SQL 編譯器產(chǎn)生的,它們應(yīng)該在執(zhí)行程序前解決。
PL/SQL 異常:類型與定義
處理異常有 3 個基本的步驟:
1、? 聲明異常(顯式或隱式地聲明)
2、? 引發(fā)異常(顯式或隱式地引發(fā))
3、? 處理異常(如果需要處理的話)
PL/SQL 異常都具有以下幾個基本特征
錯誤類型:這界定了錯誤是 ORA 錯誤或 PLS 錯誤
錯誤代碼:一串表示錯誤代碼的數(shù)字
錯誤文本:錯誤信息的文本,包括錯誤代碼
PL/SQL
的內(nèi)置錯誤
下面列出了在異常處理中使用的聲明 / 語句:
EXCEPTION 聲明 : 在聲明用戶定義的異常時,必須使用這種說明
RAISE 語句:引發(fā)異常時必須使用的指令
PRAGMA EXCEPTION_INIT 指令:把 Oracle 錯誤與用戶自定義異常關(guān)聯(lián)時使用這種指令。
SAVE EXCEPTION 子句: 這是 oracle 9i 中新增加的一個內(nèi)容,主要用于批綁定處理中,如果有一執(zhí)行失敗,則處理會繼續(xù)進行而不會停止。
函
?
數(shù)
可以使用下面兩個函數(shù)捕獲在 PL/SQL 中發(fā)生的 Oracle 錯誤信息
SQLCODE :該函數(shù)返回懷疑有錯誤的錯誤代碼
SQLERRM :該函數(shù)返回懷疑有錯誤的錯誤文本
過程
? 可以使用下面過程的 PL/SQL 中定義用戶錯誤消息。
? RAISE_APPLICATION_ERROR :可以使用這個過程來定義用戶錯誤消息和在使用該過程的位置上暫停程序的執(zhí)行。
異常處理程序
? 雖然 pl/sql 代碼塊中異常處理部分是不可缺少的,但是它對于任何 pl/sql 程序來說卻都是必要的。強烈推薦在每一個 pl/sql 程序中編寫異常處理代碼
異常處理程序是由 EXCEPTION WHEN…… 子句定義的。下面是其語法
EXCEPTION? WHEN ?exception_name THEN
…..
也可以指定多個異常,如下所示:
EXCEPTION
???? WHEN exception_nam1 THEN
????????????? …….
???? WHEN exception_nam2? THEN
????????????? ……
?????? ?WHEN OTHERS THEN
??????? ….
當 ORACLE 錯誤發(fā)生的時候,如果有個緊接著它的異常處理程序,控制就會立即轉(zhuǎn)移到該異常處理程序中;如果沒有,控制權(quán)就轉(zhuǎn)移到下一個可用的異常處理程序中;如果沒有任何異常,程序就會以一個未處理異常形式終止。
PL/SQL
異常類型
Pl/sql 中異常基本上可以分為以下幾類
1、? 預(yù)定義異常
2、? 未定義的 Oracle 異常
3、? 用戶自定義異常
4、? 用戶自定義的 PL/SQL 錯誤信息
處理
PL/SQL
異常
有兩種處理異常的方法:
1、? 處理異常以后程序繼續(xù)執(zhí)行
2、? 處理異常以后程序停止執(zhí)行
發(fā)生異常時,如果程序需要繼續(xù)執(zhí)行,則需要執(zhí)行一下以個步驟:
1、? 顯式或隱式地引發(fā)異常
2、? 對已經(jīng)引發(fā)的異常, ….
3、? 異常處理程序的代碼執(zhí)行以后,程序執(zhí)行就會相應(yīng)的恢復(fù)或終止
4、? 如果在整個程序中都沒定義異常處理程序,程序就會在引發(fā)異常的位置終止,引發(fā)異常的執(zhí)行點之后代碼就得不到執(zhí)行。
create
or
replace
procedure
p1 is
? v_temp varchar2(
200
);
begin
?? select? al_name into v_temp from addr_alias where al_id=
'aaa3'
;
?? dbms_output.put_line(
'sfsafdsafasdfdfsa'
);
end ;
在以上代碼中,執(zhí)行
select
語句是出現(xiàn)異常,不執(zhí)行
dbms_output
語句
create
or
replace
procedure
p1 is
? v_temp varchar2(
200
);
begin
?? select? al_name into v_temp from addr_alias where al_id=
'aaa3'
;
?? dbms_output.put_line(
'sfsafdsafasdfdfsa'
);
EXCEPTION? when NO_DATA_FOUND then
??? dbms_output.put_line(sqlerrm);
end ;
以上代碼加了了異常處理,執(zhí)行時輸出
:
ORA-01403: no data found
異常信息,說明在程序在
select
出現(xiàn)異常就跳轉(zhuǎn)到異常處理處,執(zhí)行異常處理程序,但并沒有執(zhí)行
dbms_output.put_line(‘a(chǎn)fasfads’);
語句輸出信息,異常出現(xiàn)
—
》處理異常
—
》結(jié)束運行。
create
or
replace
procedure
p1 is
? v_temp varchar2(
200
);
begin
?? select? al_name into v_temp from addr_alias where al_id=
'123456789'
;
?? dbms_output.put_line(
'sfsafdsafasdfdfsa'
);
EXCEPTION?
? when NO_DATA_FOUND then
??? dbms_output.put_line(sqlerrm);
? whenothersthen
??? dbms_output.put_line(
'others exception--->'
||sqlerrm);
end ;
以上代碼執(zhí)行輸出結(jié)果是
:
ORA-01403: no data found
和上一個代子一樣,這例子說明在多個異常體里,只有一個異常被執(zhí)行了。
以上例子都是程序運行時出現(xiàn)異常,而停止運行。
處理異常后繼續(xù)執(zhí)行
create
or
replace
procedure p2
is
?v_temp varchar2(
200
);
?begin
??? begin
????? select? al_name into v_temp from addr_alias where al_id=
'123456789'
;
????? dbms_output.put_line(
'ssssskkddd'
);
??? exception? when no_data_found then
????? select? al_name into v_temp from addr_alias where al_id=
'3'
;
?????? dbms_output.put_line(
'v_temp-->'
||v_temp||
'? sqlerrm-->'
||sqlerrm);
??? end ;
??? begin
????? dbms_output.put_line(
'
第二
begin end;'
);
??? exception
?????? when?? no_data_found then
?????? dbms_output.put_line(
'aaaaaaa'
);
??? end;
?exception
?? whenothersthen
???? dbms_output.put_line(
'
最外層
exception...'
);
end;
以上程序中運行時輸出的結(jié)果如下:
v_temp-->
龍口
..? sqlerrm-->ORA-01403: no data found
第二層
begin end;
結(jié)果說明在第一個
begin end;
執(zhí)行時發(fā)了異常,就執(zhí)到行該層的
exception
來處理異常,異常處理完后執(zhí)行第二個
begin end;
的代碼,當你把第一層
begin end;
中的異常處理部分注釋掉后,輸出的結(jié)果如下
:
最外層
exception...
這結(jié)果說明了,在第一個
begin end;
中因為沒有異常處理模塊,所以程序跳到上一層尋找異常處模塊來處理異常,同第一個
begin end;
同一個層次的第二個
begin end;
模塊的代碼就不會執(zhí)行,如果在最外層也找不到異常處理模塊就執(zhí)行默認的異常處理模塊。
處理用戶自定義異常
用戶自定義異常,像其它
pl/sql
一親友,顯式地聲明用戶自定義異常。可以使用
EXCEPTION
關(guān)鍵字指定這些異常的數(shù)據(jù)類型。其語法如下
:
1
、定義自定義異常
Exception_name EXCEPTION;
注意:必須用
EXCEPTION
關(guān)鍵字定義用戶自定義異常
?????
用戶自定義異常不與任何錯誤代碼或錯誤文本關(guān)聯(lián)
2
、使用
RAISE
語句引發(fā)用戶自定義異常
?????? Raise? exception_name;
例子
:
Declare
?? Examp_exception? EXCEPTION;
Begin
?? If? (
條件
)? then
????????????? Raise examp_exception;
?? End if;
Exception
? When examp_exception then
?? ……
End;
處理聲明和異常處理部分引發(fā)的異常
1、?
在聲明部分引發(fā)的異常
在聲明部分引發(fā)的異常必須在其緊接著的封閉塊(
begin ..end
)中的相關(guān)處理程序中進行處理。如果緊接著的封閉塊中不存在該處理程序,控制就會轉(zhuǎn)到有該處理程序的第一個封閉塊。
如
Declare
? V_num number(2) :=100
Begin
? Null;
..
Exception
? when value_error then
???? null;
? when others then
??? null;
End;
這樣的定義是不能正確處理掉聲時所產(chǎn)生的異常。為此必須定義一個封閉塊來處理該封閉塊的聲明部分引發(fā)的異常,代碼如下
:
Declare
? V_num number(2) :=100
Begin
? Null;
..
Exception
? when value_error then
???? null;
? when others then
??? null;
End;
Exception
? when value_error then
???? dbms_output.put_line(‘value error occurred’);
?? when others then
??? dbms_output.put_line(‘…’);
End;
這樣才能正確的處理聲明時的異常
2、?
處理異常部分引發(fā)的異常
只能在異常模塊的內(nèi)部引發(fā)
(raise)
外部異常。如:
Declare
Excep1 exception;
Excep2 exception;
?? Begin
????????????? Begin
???????????????????? If? (
條件
)?? then
??????????????? Raise excep1;
??????????? End if;
????????????? Exception
???????????????????? When excep1 then
???????????? Raise excep2;
??????? End;
?????? Exception
????????????? When excep2 then
???????????????????? Null;
??????? When others then
????????
??Dbms_output.put_line(‘………..’);
?? End;
關(guān)于異常的我想這么多夠用了,異常這一節(jié)還有其它的一些內(nèi)容。