--============PLSQL==異常處理=============================
-- Exception是一種PL/SQL標識符,當運行的PL/SQL塊出現錯誤或警告,則會觸發異常處理。
--PLSQL錯誤
----編譯時錯誤
----運行時錯誤
--運行時錯誤
---- oracle錯誤 (ora-xxx)
---- PL/SQL運行錯誤
---- 用戶定義的條件
--==========ORACLE錯誤處理機制===============
---- 在程序運行期間的錯誤對應一個異常Exception.
---- 當錯誤產生時拋出相應的異常.並被異常處理器捕獲,
---- 程序控制權傳遞給異常處理器,由異常處理器來處理運行時錯誤.
---=========異常的觸發類型==================
--隱士觸發
----- oracle預定義異常
----- 非oracle預定義異常
--顯式觸發
----- 用戶自定義異常
-- ========異常運行機制=====================
--異常捕獲通過異常處理器實現,它是程序的一個獨立部分.
--把錯誤與程序的其它部分分離開來,使程序邏輯更加易於理解.
--當異常產生時,控制權立即轉移到異常處理器,一旦執行控制權被轉移到異常處理器,
--就無法再回到本語句塊的可執行部分,如果沒有異常部分,則被傳播到外層語句塊.
--==異常處理語法:
exception
when 異常名字1 then 處理異常語句1;
when 異常名字2 or 異常名字3 then 處理異常語句2;
when others then 其它處理3;
-- 允許有多個異常處理器
end;
--Exception關鍵字:標識異常處理的開始區域.
--一個異常處理器可以捕獲多個異常,只需要在when子句中用or連接即可
--一個異常只能被一個異常處理器捕獲,並進行處理.
-- others異常處理器總是作爲異常處理最後一個異常處理器 ,
-- 負責處理那些沒有被其他異常處理器捕獲的異常.
--========Oracle預定義錯誤的捕獲============
--no_data_found
--too_many_rows
--ZERO_DIVIDE
--演示 ORACLE預定義異常捕獲的語法 ZERO_DIVIDE異常==========
declare
v_id number(4) ;
begin
select deptno into v_id from emp where 1= 2;--no_data_found Exception
--select deptno into v_id from emp where 1= 1/0;--ZERO_DIVIDE Exception
Exception
when ZERO_DIVIDE
then dbms_output.put_line('ZERO_DIVIDE Exception');
when no_data_found
then dbms_output.put_line('no_data_found Exception');
when others
then dbms_output.put_line(' Exception');
end;
-- 演示關聯數組的異常
declare
type ind_tab_array is
table of number index by binary_integer;
ind_tab ind_tab_array; --自動初始化null
begin
--ind_tab(null) :=3 VALUE_ERROR
if(ind_tab(1)) =1 --NO_DATA_FOUND
then dbms_output.put_line(ind_tab(1));
end if;
Exception
when VALUE_ERROR
then dbms_output.put_line('VALUE_ERROR');
when NO_DATA_FOUND
then dbms_output.put_line('NO_DATA_FOUND');
end;
--===============非預定義異常==============
--非預定義異常:某些異常在oracle中沒有定義名詞,只有一個ORA-xxxx,
SQL> insert into emp(empno ) values (null);
insert into emp(empno ) values (null)
*
第 1 行出現錯誤:
ORA-01400: 無法將 NULL 插入 ("SCOTT"."EMP"."EMPNO")
--我們把這樣的異常定義一個名字(將異常名與異常編號相關聯),稱之爲非預定義異常
--使用的基本過程
--a.定義一個異常名 (declare)
--b.將異常名與異常編號相關聯(associate)
--c.在異常處理部分捕捉並處理異常(reference)
declare
e_key Exception;--定義
pragma exception_init(e_key,-01400);--綁定關聯
begin
insert into emp(empno ) values (null);
Exception
when e_key
then dbms_output.put_line('e_key');
when others
then dbms_output.put_line('unknow exception');
end;
--========用戶自定義異常============
--自定義異常與Oracle錯誤沒有任何關係,有開發人員爲特定情況所定義的例外
--使用的基本過程
--a.用戶自定義異常必須在聲明部分進行聲明
--b.當異常發生時,系統不能自動觸發,需要使用Raise語句觸發
--c.在異常處理部分捕獲並處理異常
--上述異常改成 用戶自定義異常
declare
e_key Exception ;
empno number(4);
begin
if empno is null
then Raise e_key; --如果是null,觸發異常
end if;
empno :=8080;
insert into emp(empno) values (empno);
Exception
when e_key
then dbms_output.put_line('e_key');
when others
then dbms_output.put_line('exception');
end;