今晚看了關於pl/sql異常傳播的內容,做個筆記。
1.pl/sql執行語句塊發生執行時錯誤
pl/sql 語句塊的可執行部分發生某個執行時錯誤,執行權會轉到該語句塊的異常處理部分。當與該異常相關的語句執行完畢之後,執行權會轉到主機環境或者外圍語句塊。如果不存在該錯誤的異常處理程式,該異常就會被傳播到外圍語句塊,然後再次執行剛才所描述的步驟。如果沒有發現異常處理程式,則程式執行會終止,執行權會轉到主機環境。請看下例:
1begin
2declare
3 a number :=4;
4 b number :=0;
5begin
6 a := a/
b;7 dbms_output.put_line('
a is '||
a);8
exception
9when zero_divide then dbms_output.put_line('
inner zero divide');
10end
;11 dbms_output.put_line('
can u see me?');
12end;
執行之後在第6行丟擲乙個異常,執行權轉到exception,在裡面**獲,並執行相應語句,此後執行權轉到外圍語句塊。因此第7行不會執行,轉而執行第11行。
所以輸出結果是:
1inner zero divide
2 can u see me?
但如果在內部的異常處理塊無法與之匹配捕獲,那麼異常將傳播到外圍語句塊的異常處理部分進行處理,來看下面的例子:
1begin
2declare
3 a number :=4;
4 b number :=0;
5begin
6 a := a/
b;7 dbms_output.put_line('
a is '||
a);8
exception
9when value_error then dbms_output.put_line('
inner value error');
10end
;11 dbms_output.put_line('
can u see me?');
12exception
13when zero_divide then dbms_output.put_line('
outter zero divide');
14end;
在第6行丟擲異常後,執行權轉換到異常處理塊,同樣第7行不會執行。在內部異常處理塊,該異常不是value_error,那麼異常將傳播到外圍語句塊的異常處理部分,因此第11行不會執行,在第13行捕獲異常,輸出語句。
1 outter zero divide
如果異常在內部就捕獲了,即使內部異常處理的型別與外部異常處理的型別一樣,也不會傳播到外部,因為已經在內部處理了。因此將上面第9行的value_error改為與外面一樣的zero_divide,第13行照樣執行。
2.pl/sql語句塊宣告部分發生執行時錯誤
pl/sql語句塊宣告部分發生執行時錯誤,如果沒有外圍語句塊,執行權將轉換到主機環境(即報錯),而不會轉到該塊的異常處理部分。那麼要捕獲該異常,只需要在外部加上語句塊即可。
1begin
2declare
3 a char(2) :=
'hello';
4begin
5 dbms_output.put_line('
a is '||
a);6
exception
7when invalid_number or value_error then dbms_output.put_line('
inner error');
8end
;9 dbms_output.put_line('
hello world');
10exception
11when invalid_number or value_error then dbms_output.put_line('
outter error');
12end;
如上面**,在宣告部分丟擲異常,接下來異常被傳播到第10行的外部異常處理部分,因此第5和第9行都不會執行,第11行被執行,輸出如下。
1 outter error
3.再次丟擲異常
在有些情況下,也許希望當發生特定型別的錯誤時,能夠停止當前程式。也就是說,在內部丟擲異常後,如果在內部處理完那麼外部語句將繼續執行,如果想一出現異常就停止程式,那麼可以將異常傳遞到外部語句塊,讓外部語句塊的異常處理部分進行處理,這個過程叫再次丟擲異常。關鍵在於內部捕獲到異常後,使用raise關鍵字將其傳播出去。
1begin
2declare
3 a char(2);4
begin
5 a :=
'hello';
6 dbms_output.put_line('
a is '||
a);7
exception
8when invalid_number or value_error then
raise;
9end
;10 dbms_output.put_line('
hello world');
11exception
12when invalid_number or value_error then dbms_output.put_line('
outter error');
13end;
如上面**,第8行捕獲到異常後,將其再次丟擲,被外部程式所捕獲,因此外部的第10行不會被執行,結果如下:
1 outter error
明晚繼續努力,學習異常的高階概念。
PLSQL 的異常處理
任何一種程式語言中的異常處理部分都是比較重要的一部分,單獨學習一下。一 異常的種類及基本用法 1 預定義異常 總計21種,具體見文件 使用方法 begin select select select exception when no data found then 常用型別 no data foun...
pl sql異常處理
丟擲異常 oracle有三種型別的異常錯誤 1 預定義 predefined 異常 oracle預定義的異常情況大約有24個。對這種異常情況的處理,無需在程式中定義,由oracle自動將其引發。2 非預定義 predefined 異常 即其他標準的oracle錯誤。對這種異常情況的處理,需要使用者在...
PLSQL 異常處理
1.異常塊begin pl sql塊 exception when no data found then 沒有找到資料 響應命令 when too many rows then 返回多行,隱式游標每次只能檢索一行資料 響應命令 when invalid number then 字元向數字轉換失敗 響...