預定義錯誤型別
今天一個朋友在MSN上問一個問題。他在PL/SQL程式碼的時候,需要捕獲主鍵插入重複異常。他說,有沒有類似於“NO_DATA_FOUND”型別的常量資訊來指代這種錯誤,然後好進行錯誤處理。
這個問題涉及到Oracle PL/SQL程式碼的錯誤處理機制,以及預定義的錯誤資訊,這裡簡單說一下。
Oracle的PL/SQL語言作為一種獨立語言出現,極大彌補了純SQL語句上的缺陷和不足。加入過程化因素,使得在資料庫端實現複雜業務邏輯的目標得以實現。作為一種獨立程式語言,錯誤異常處理(Error/Exception Handle)是一個不可或缺的部分。
異常Exception發生的原因有很多,比如設計缺陷、程式碼錯誤、業務資料缺陷和軟硬體故障等等。在開發階段預想到所有可能發生的異常是不可能的,但是作為開發人員,我們是可以捕獲和處理異常的。正確捕獲和處理異常非常重要,特別是進行一些關鍵的DML操作,要保證資料和業務的完整性。
Oracle中的Exception有兩種,一種是內部定義的(也成為執行時異常)、另一種是使用者定義異常。內部異常透過編號進行標誌,例如ORA_XXXX。內部錯誤是由Oracle內部定義,並且由Oracle自己去檢測激發。一些常見的內部異常,是有自己的預定義名稱的。如我們常見的TOO_MANY_ROWS、ZERO_DIVIDE等。朋友的意思也就是找到匹配“主鍵重複”錯誤的預定義名稱。
對異常的處理,首先談到的是異常的檢測。在目前流行的語言(如Java、C#)中,都是採用類似“try…catch…finally”的結構。在一段程式碼中檢測異常,當發生的時候,透過層層檢驗捕捉。最後使用finally進行資源回收。
Oracle的pl/sql同樣採用了這種類似的結構。是使用一個begin---end塊包裹,如下:
set serveroutput on size 10000;
declare
n_totalsal number :=1000;
n_number number :=0;
n_price number;
begin
n_price := n_totalsal/n_number;
exception
when too_many_rows then
dbms_output.put_line('Too Many Data Found !');
when zero_divide then
dbms_output.put_line('zero_divide');
when others then
dbms_output.put_line('Others');
end;
/
這段程式碼,最終生成異常,並且被zero_divide所攔截。匿名塊返回結果為:
SQL>
zero_divide
PL/SQL procedure successfully completed
在Oracle中,同樣存在一些像too_many_rows這種預定義的錯誤資訊。下面從參考文獻中找出歸納。
異常名稱 |
ORA ERROR |
SQLCODE |
含義和丟擲點 |
ACCESS_INTO_NULL |
06530 |
-6530 |
當程式給一個未初始化物件的屬性賦值時候,丟擲; |
CASE_NOT_FOUND |
06592 |
-6592 |
使用Case語句的時候,沒有使用else字句,並且when的情況不能覆蓋; |
COLLECTION_IS_NULL |
06531 |
-6531 |
當呼叫一個未初始化陣列或者集合物件的非Exists方法,或者對一個為未初始化陣列集合賦值; |
CURSOR_ALREADY_OPEN |
06511 |
-6511 |
程式試圖開啟一個已經開啟的cursor。開啟遊標只能是針對一個關閉的遊標進行; |
DUP_VAL_ON_INDEX |
00001 |
-1 |
違反索引唯一約束; |
INVALID_CURSOR |
01001 |
-1001 |
對遊標進行非法操作,比如關閉一個處在非開啟狀態的遊標; |
INVALID_NUMBER |
01722 |
-1722 |
數字型別轉換錯誤; |
LOGIN_DENIED |
01017 |
|
非法使用者名稱密碼登入; |
NO_DATA_FOUND |
01403 |
+100 |
使用select into的時候,如果沒有返回值; |
NOT_LOGGED_ON |
01012 |
-1012 |
在沒有登入的情況下,呼叫資料庫操作命令; |
PROGRAM_ERROR |
06501 |
-6501 |
PL/SQL發生了內部錯誤; |
ROWTYPE_MISMATCH |
06504 |
-6504 |
本地遊標和PL/SQL遊標返回型別不匹配; |
SELF_IS_NULL |
30625 |
-30625 |
試圖呼叫一個沒有初始化的物件的方法成員,因為關鍵字SELF表示的是物件的自生(是內建引數),在呼叫時候總是第一個傳遞給方法成員。 |
STORAGE_ERROR |
06500 |
-6500 |
PL/SQL程式碼超出記憶體或者記憶體崩潰; |
SUBSCRIPT_BEYOND_COUNT |
06533 |
-6533 |
訪問陣列、集合的時候,地址index超過下標界限(過上界); |
SUBSCRIPT_OUTSIDE_LIMIT |
06532 |
-6532 |
訪問陣列、集合的時候,地址index超過下標界限(過下界); |
SYS_INVALID_ROWID |
01410 |
-1410 |
將一個字串轉化為rowid的時候,發現非法; |
TIMEOUT_ON_RESOUCE |
00051 |
-51 |
當資料庫等待一個執行資源的時候,操作cursor超時; |
TOO_MANY_ROWS |
01422 |
-1422 |
Select into語句返回了多條記錄; |
VALUE_ERROR |
06502 |
-6502 |
數字演算法、轉換或者源於長度限制的錯誤; |
ZERO_DIVIDE |
01476 |
-1476 |
除零; |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-687040/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 自定義錯誤型別時應該注意的 nil !=nil型別
- ES5 / ES6 自定義錯誤型別比較型別
- SQL未明確定義列錯誤SQL
- mybatis引數型別錯誤MyBatis型別
- 程式錯誤型別及其處理型別
- MySQL主從複製錯誤——列型別轉換錯誤MySql型別
- Golang通脈之型別定義Golang型別
- 常見的錯誤日誌型別型別
- IIS瀏覽器422、500等錯誤提示:自定義錯誤模組不能識別此錯誤瀏覽器
- 匯入sql時報日期型別錯誤SQL型別
- 定義一個單例型別的Qml單例型別
- 關於Mapreduce Text型別賦值的錯誤型別賦值
- 建議欄位別名定義定義那裡順便可定義預設值,這預設值還可以是函式函式
- vue3 子元件 ref ts型別定義Vue元件型別
- JAVASE——資料型別,變數定義及使用Java資料型別變數
- Typescript 下 Mongoose 外來鍵型別&外來鍵陣列型別定義&型別保護&聯合型別理解TypeScriptGo型別陣列
- tomcat配置400/404/500型別的錯誤頁面,修改專案預設路徑,修改預設專案Tomcat型別
- 自定義型別型別
- 型別預設和any型別型別
- 物聯網學習教程—用typedef定義型別型別
- 函式引數 引數定義函式型別函式型別
- [需求建議]建議欄位別名定義定義那裡順便可定義預設值,這預設值還可以是函式函式
- 關於mysql中欄位定義的型別int、tinyint區別MySql型別
- 自定義OAM錯誤頁面
- 錯誤記錄:apache預設網頁訪問錯誤Apache網頁
- golang基礎語法,定義函式型別 為已存在的資料型別起別名Golang函式資料型別
- SQL中欄位比較型別不匹配錯誤:‘cannot be cast to’SQL型別AST
- 建構函式定義的隱式型別轉換函式型別
- 定義多維的點模板類,任意資料型別資料型別
- 如何在Typescript中定義Promise的返回值型別TypeScriptPromise型別
- Logger級別定義
- 教你自定義Flutter錯誤頁面Flutter
- 七、Spring Boot 錯誤處理原理 & 定製錯誤頁面Spring Boot
- [譯]RxJava 的全面介紹:Observable 型別、背壓、錯誤處理RxJava型別
- XML Schema 複雜元素型別詳解:定義及示例解析XML型別
- 認真一點學 Go:12. 自定義型別和結構體 - 定義Go型別結構體
- 自定義資料型別資料型別
- 型別自定義格式字串型別字串
- JavaScript報錯型別(報錯速查)JavaScript型別