在
PL / SQL
中錯誤信息處理過程分為兩步:
引發錯誤和處理錯誤。編譯處誤是由
PL/SQL
編譯器產生的,它們應該在執行程序前解決。
?
?
PL/SQL
異常:類型與定義
處理異常有
3
個基本的步驟:
1、?
聲明異常(顯式或隱式地聲明)
2、?
引發異常(顯式或隱式地引發)
3、?
處理異常(如果需要處理的話)
?
?
PL/SQL
異常都具有以下幾個基本特征
?
錯誤類型:這界定了錯誤是
ORA
錯誤或
PLS
錯誤
錯誤代碼:一串表示錯誤代碼的數字
錯誤文本:錯誤信息的文本,包括錯誤代碼
?
?
PL/SQL
的內置錯誤
?
下面列出了在異常處理中使用的聲明
/
語句:
EXCEPTION
聲明
:
在聲明用戶定義的異常時,必須使用這種說明
RAISE
語句:引發異常時必須使用的指令
PRAGMA EXCEPTION_INIT
指令:把
Oracle
錯誤與用戶自定義異常關聯時使用這種指令。
SAVE EXCEPTION
子句:
這是
oracle 9i
中新增加的一個內容,主要用于批綁定處理中,如果有一執行失敗,則處理會繼續進行而不會停止。
?
函
?
數
可以使用下面兩個函數捕獲在
PL/SQL
中發生的
Oracle
錯誤信息
SQLCODE
:該函數返回懷疑有錯誤的錯誤代碼
SQLERRM
:該函數返回懷疑有錯誤的錯誤文本
?
過程
?
可以使用下面過程的
PL/SQL
中定義用戶錯誤消息。
? RAISE_APPLICATION_ERROR
:可以使用這個過程來定義用戶錯誤消息和在使用該過程的位置上暫停程序的執行。
?
?
異常處理程序
?
雖然
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
錯誤發生的時候,如果有個緊接著它的異常處理程序,控制就會立即轉移到該異常處理程序中;如果沒有,控制權就轉移到下一個可用的異常處理程序中;如果沒有任何異常,程序就會以一個未處理異常形式終止。
?
?
PL/SQL
異常類型
Pl/sql
中異常基本上可以分為以下幾類
1、?
預定義異常
2、?
未定義的
Oracle
異常
3、?
用戶自定義異常
4、?
用戶自定義的
PL/SQL
錯誤信息
?
處理
PL/SQL
異常
?
有兩種處理異常的方法:
1、?
處理異常以后程序繼續執行
2、?
處理異常以后程序停止執行
發生異常時,如果程序需要繼續執行,則需要執行一下以個步驟:
1、?
顯式或隱式地引發異常
2、?
對已經引發的異常,
….
3、?
異常處理程序的代碼執行以后,程序執行就會相應的恢復或終止
4、?
如果在整個程序中都沒定義異常處理程序,程序就會在引發異常的位置終止,引發異常的執行點之后代碼就得不到執行。
?
?
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 ;
在以上代碼中,執行
select
語句是出現異常,不執行
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 ;
以上代碼加了了異常處理,執行時輸出
:
ORA-01403: no data found
異常信息,說明在程序在
select
出現異常就跳轉到異常處理處,執行異常處理程序,但并沒有執行
dbms_output.put_line(‘afasfads’);
語句輸出信息,異常出現
—
》處理異常
—
》結束運行。
?
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 ;
以上代碼執行輸出結果是
:
ORA-01403: no data found
和上一個代子一樣,這例子說明在多個異常體里,只有一個異常被執行了。
?
?
以上例子都是程序運行時出現異常,而停止運行。
?
處理異常后繼續執行
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;
以上程序中運行時輸出的結果如下:
v_temp-->
龍口
..? sqlerrm-->ORA-01403: no data found
第二層
begin end;
?
結果說明在第一個
begin end;
執行時發了異常,就執到行該層的
exception
來處理異常,異常處理完后執行第二個
begin end;
的代碼,當你把第一層
begin end;
中的異常處理部分注釋掉后,輸出的結果如下
:
最外層
exception...
這結果說明了,在第一個
begin end;
中因為沒有異常處理模塊,所以程序跳到上一層尋找異常處模塊來處理異常,同第一個
begin end;
同一個層次的第二個
begin end;
模塊的代碼就不會執行,如果在最外層也找不到異常處理模塊就執行默認的異常處理模塊。
?
處理用戶自定義異常
?
用戶自定義異常,像其它
pl/sql
一親友,顯式地聲明用戶自定義異常。可以使用
EXCEPTION
關鍵字指定這些異常的數據類型。其語法如下
:
1
、定義自定義異常
Exception_name EXCEPTION;
?
注意:必須用
EXCEPTION
關鍵字定義用戶自定義異常
?????
用戶自定義異常不與任何錯誤代碼或錯誤文本關聯
2
、使用
RAISE
語句引發用戶自定義異常
?????? Raise? exception_name;
例子
:
Declare
?? Examp_exception? EXCEPTION;
Begin
?? If? (
條件
)? then
????????????? Raise examp_exception;
?? End if;
Exception
? When examp_exception then
?? ……
End;
?
處理聲明和異常處理部分引發的異常
1、?
在聲明部分引發的異常
在聲明部分引發的異常必須在其緊接著的封閉塊(
begin ..end
)中的相關處理程序中進行處理。如果緊接著的封閉塊中不存在該處理程序,控制就會轉到有該處理程序的第一個封閉塊。
如
Declare
? V_num number(2) :=100
Begin
? Null;
..
Exception
? when value_error then
???? null;
? when others then
??? null;
End;
這樣的定義是不能正確處理掉聲時所產生的異常。為此必須定義一個封閉塊來處理該封閉塊的聲明部分引發的異常,代碼如下
:
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、?
處理異常部分引發的異常
只能在異常模塊的內部引發
(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;
?
關于異常的我想這么多夠用了,異常這一節還有其它的一些內容。
posted on 2006-09-19 18:09
有貓相伴的日子 閱讀(6773)
評論(2) 編輯 收藏 所屬分類:
pl/sql