oracle提供了預定義例外、非預定義例外和自定義例外三種類型。其中:
l預定義例外用于處理常見的oracle錯誤;
l非預定義例外用于處理預定義所不能處理的oracle錯誤;
l自定義例外處理與oracle錯誤無關的其他情況。
Oracle代碼編寫過程中,如果捕捉例外則會在plsql塊內解決運行錯誤,否則將錯誤傳遞到調用環境。
常用預定義例外:
為了處理各種常見的oracle錯誤,plsql為開發人員提供了二十多個預定義例外,每個預定義例外都對應一個oracle系統錯誤。
Access_info_null(ora-06530):當訪問沒有初始化的對象時觸發。
Case_not_found(ora-06592):在case過程中when后沒有包含必要的條件分支并且沒有else子句,則會觸發本異常。
Collection_is_null(ora-06531):訪問未初始化的集合元素(嵌套表或者varray)。
Cursor_already_open(ora-06511):重新打開已經打開的游標。
Dup_val_on_index(ora-00001):當中唯一索引所對應的列上鍵入重復值時。
Invalid_cursor(ora-01001):試圖在不合法的游標上執行操作時,譬如沒打開游標就提取內容。
Invalid_number(ora-01722):當試圖將非法的字符串轉換為數字類型時。
No_data_found(ora-01403):執行select into未返回行,或者引用了索引表未初始化的元素時。
Too_many_rows(ora-01422):執行select into返回超過一行數據時。
Zero_divide(ora-01476):0作為被除數時。
Subscript_beyond_count(ora-06533):使用嵌套表或者varray集合時,如果引用下標超過last。
Subscript_outside_limit(ora-06532):使用嵌套表或varray集合時,如果引用下標小于first。
Value_error(ora-06502):在執行賦值操作時,如果變量長度不足以容納實際數據。
Login_denied(ora-01017):連接數據庫時提供了不正確的用戶名或口令。
Not_logged_on(ora-01012):在程序沒有連接到oracle數據庫時執行plsql代碼則會觸發。
Program_error(ora-06501):plsql內部問題。
Rowtype_mismatch(ora-06504):執行賦值操作時,如果宿主游標變量和PLSQL游標變量返回類型不兼容時。
Self_is_null(ora-30625):使用對象類型時,如果在null實例上調用成員方法。
Storage_error(ora-06500):超出內存空間或者內存被損壞。
Sys_invalid_rowid(ora-01410):無效字符串企圖轉換為rowid類型時。
Timeout_on_resource(ora-00051):等待資源時出現超時錯誤。
處理非預定義例外:
上面描述的21中預定義之外的其他oracle錯誤通稱為非預定義例外,對這種例外的處理包括三步:首先的定義部分定義例外;然后使用progma exception(exception_name,exception_number) 在例外和oracle錯誤之間建立關聯,這時要求用戶知道可能出現的錯誤號(例外函數sqlcode、sqlerrm和raise_application_error);最終在例外處理部分捕捉并處理例外。
DeclareE_integrity exceptionPragma exception_init(e_integrity,-2291);BeginSqlstatement;ExceptionWhen e_integrity thenDbms_output.put_line(‘數據完整性錯誤。’);End;
處理自定義例外:
預定義例外和非預定義例外都跟oracle錯誤有關,而自定義例外則是用戶根據業務處理時特定的情況而自定義的例外。使用自定義例外時,首先需要在定義部分declare定義例外,然后在執行部分觸發例外(使用raise語句),最后在例外處理部分捕捉并處理例外。
declaremyexception exception;beginif1=0 thenraise myexception;endif;exceptionwhen myexception thendbms_output.put_line('asdf');end;
使用例外函數:
oracle內置函數sqlcode和sqlerrm主要用在others處理器中,分別用來返回oracle的錯誤代碼和錯誤消息。一般情況下sqlcode返回負數標識的oracle錯誤代碼,除非錯誤為‘ora-01403:no data found’此時對應的sqlcode為+100,對于用戶自定義的異常,sqlcode返回+1,如果沒有異常被觸發,sqlcode返回0。
BeginExceptionWhen others thenDbms_output.put_line(sqlcode||sqlerrm(sqlcode));End;
Oracle過程raise_application_error用于在plsql應用程序中自定義錯誤消息。注意該過程只能在數據庫端的子程序(過程、函數、包、觸發器)中使用,而不能在匿名塊和客戶端的子程序中使用。語法為raise_application_error(error_number,message[,[true|false]]);其中error_number用于定義錯誤號,該錯誤號必須在-20000到-20999之間的負整數;message用于指定錯誤消息,并且該消息的長度不能超過2048字節;第三個參數如果為true,則該錯誤會被放在先前錯誤堆棧中,如果為false(默認值)則會替代先前所有錯誤。
plsql編譯警告:
plsql警告可以分為三類,severe用于檢查可能出現的不可預料或者錯誤結果,例如參數的別名問題;performance用于檢查可能引起的性能問題,例如執行insert操作時為number列提供了varchar2類型數據;informational用于檢查子程序中的死代碼;all用于檢查所有警告。為了數據庫可以在編譯plsql子程序時發出警告信息,需要設置初始化參數plsql_warnings。這個參數不僅可以在系統級或者會話級設置,也可以在alter procedure命令中設置。Alter {system|session|procedure} set plsql_warnings=’{enable|disable:{all |performance|severe|informational}}’;為了檢查是否存在對應警告信息,必須先激活警告檢查,然后重新編譯子程序,最后使用show errors命令顯示警告錯誤。
create or replace procedure my_testisbeginif1=0thendbms_output.put_line('test');endif;end;SQL> alter procedure my_test compile plsql_warnings = 'enable:all';Procedure alteredSQL> show errors;Errors for PROCEDURE SYS.MY_TEST:LINE/COL ERROR-------- -------------------------10/5???? PLW-06002: 無法執行的代碼————————————————