標籤:
Oracle異常分類
- Oracle預定義異常(即已定義的內部異常)
- Oracle非預定義異常(即未定義的內部異常)
- 使用者自訂異常
常見的預定義異常
NO_DATA_FOUND 語句沒有查詢出合格記錄返回
TOO_MANY_ROWS 語句合格記錄有多條返回
DUP_VAL_ON_INDEX 資料庫表中的某一條有唯一索引,程式試圖儲存兩個重複的值
VALUE_ERROR 在轉換字元類型,截取或長度受限發生異常,如聲明的長度比字元短
STORAGE_ERROR 記憶體溢出
ZERO_DRIVIDE 除數為零
CAST_NOT_FOUND case語句沒有相匹配的條件,同時也沒有else語句
CURSOR_ALREADY_OPEN 程式試圖開啟一個已經開啟的遊標
TIMEOUT_ON_RESOURCE 系統在等待某一資源,系統逾時
ACCESS_INTO_NULL 為對象賦值前必需初始化對象
INVALID_NUMBER 不能將字元轉換成數字
TRANSACTION_BACKED_OUT 由於死結提交被退出
常見的非預定義異常
如果要處理未聲明的內部異常,必須使用OTHERS異常處理器或PRAGMA EXCEPTION_INIT
others
pragma exception_init(exception_name,-Oracle_error_number)
用法:
DECLARE
deadlock_detected EXCEPTION;
PRAGMA EXCEPTION_INIT(deadlock_detected, -60); --關聯一個oracle內部的錯誤號碼
BEGIN
... -- Some operation that causes an ORA-00060 error
EXCEPTION
WHEN deadlock_detected THEN --由oracle系統自動觸發
-- handle the error
END;
ORA-00001: 違反唯一約束條件 (.)
ORA-00017: 請求會話以設定跟蹤事件
ORA-00018: 超出最大會話數
ORA-00019: 超出最大會話許可數
ORA-00020: 超出最大進程數 ()
ORA-00021: 會話附屬於其它某些進程;無法轉換會話
ORA-00022: 無效的會話 ID;訪問被拒絕
ORA-00023: 會話引用進程私用記憶體;無法分離會話
ORA-00024: 單一進程模式下不允許從多個進程註冊
ORA-00025: 無法分配
ORA-00026: 丟失或無效的會話 ID
ORA-00027: 無法刪去當前會話
ORA-00028: 您的會話己被刪去
ORA-00029: 會話不是使用者會話
ORA-00030: 使用者會話 ID 不存在。
ORA-00031: 標記要刪去的會話
ORA-00032: 無效的會話移植口令
ORA-00033: 當前的會話具有空的移植口令
ORA-00034: 無法在當前 PL/SQL 會話中
ORA-00035: LICENSE_MAX_USERS 不能小於目前使用者數
ORA-00036: 超過遞迴 SQL () 級的最大值
ORA-00037: 無法轉換到屬於不同伺服器組的會話
ORA-00038: 無法建立會話: 伺服器組屬於其它使用者
ORA-00050: 擷取入隊時作業系統出錯
ORA-00051: 等待資源逾時
ORA-00052: 超出最大入隊資源數 ()
ORA-00053: 超出最大入隊數
ORA-00054: 資源正忙,要求指定 NOWAIT
ORA-00055: 超出 DML 鎖的最大數
ORA-00056: 對象 ‘.‘ 上的 DDL 鎖以不相容模式掛起
ORA-00057: 超出暫存資料表鎖的最大數
ORA-00058: DB_BLOCK_SIZE 必須為才可安裝此資料庫 (非 )
ORA-00059: 超出 DB_FILES 的最大值
ORA-00060: 等待資源時檢測到死結
ORA-00061: 另一個常式設定了不同的 DML_LOCKS
ORA-00062: 無法獲得 DML 全表鎖定;DML_LOCKS 為 0
ORA-00063: 超出 LOG_FILES 的最大數
ORA-00064: 對象過大以至無法分配在此 O/S (,)
ORA-00065: FIXED_DATE 的初始化失敗
ORA-00066: LOG_FILES 為 但需要成為 才可相容
ORA-00067: 值 對參數 無效;至少必須為
ORA-00068: 值 對參數 無效,必須在 和 之間
ORA-00069: 無法獲得鎖定 -- 禁用了表鎖定
ORA-00070: 命令無效
ORA-00071: 進程號必須介於 1 和 之間
ORA-00072: 進程""不活動
ORA-00073: 命令 介於 和 個參數之間時使用
ORA-00074: 未指定進程
ORA-00075: 在此常式未找到進程 ""
ORA-00076: 未找到轉儲
ORA-00077: 轉儲 無效
ORA-00078: 無法按名稱轉儲變數
ORA-00079: 未找到變數
ORA-00080: 層次 指定的全域地區無效
ORA-00081: 位址範圍 [,) 不可讀
ORA-00082: 的記憶體大小不在有效集合 [1], [2], [4] 之內
ORA-00083: 警告: 可能損壞映射的 SGA
ORA-00084: 全域地區必須為 PGA, SGA 或 UGA
ORA-00085: 當前調用不存在
ORA-00086: 使用者調用不存在
ORA-00087: 命令無法在遠程常式上執行
ORA-00088: 共用伺服器無法執行命令
ORA-00089: ORADEBUG 命令中無效的常式號
ORA-00090: 未能將記憶體配置給群集資料庫 ORADEBUG 命令
ORA-00091: LARGE_POOL_SIZE 至少必須為
ORA-00092: LARGE_POOL_SIZE 必須大於 LARGE_POOL_MIN_ALLOC
ORA-00093: 必須介於 和 之間
ORA-00094: 要求整數值
ORA-00096: 值 對參數 無效,它必須來自 之間
ORA-00097: 使用 Oracle SQL 特性不在 SQL92 級中
ORA-00099: 等待資源時發生逾時,可能是 PDML 死結所致
ORA-00100: 未找到資料
ORA-00101: 系統參數 DISPATCHERS 的說明無效
ORA-00102: 發送器無法使用網路通訊協定
ORA-00103: 無效的網路通訊協定;供發送器備用
ORA-00104: 檢測到死結;全部公用伺服器鎖定等待資源
自訂異常
預定義異常和非預定義異常都與Oracle內部錯誤有關,並且當出現Oracle錯誤時會隱含觸發相應異常;
而自訂異常與Oracle錯誤沒有任何關聯,它是由開發人員為特定情況所定義的異常,需手工觸發。
步驟
1.定義異常
2.觸發異常(RAISE或RAISE_APPLICATION_ERROR)
3.異常處理
例如:
DECLARE ERROR1 EXCEPTION; ERROR2 EXCEPTION;BEGIN IF 5 = 5 THEN RAISE ERROR1; ELSIF 5 > 6 THEN RAISE ERROR2; END IF;EXCEPTION WHEN ERROR1 THEN DBMS_OUTPUT.PUT_LINE(‘5等於5‘); WHEN ERROR2 THEN DBMS_OUTPUT.PUT_LINE(‘5大於5‘);END;
RAISE 異常名,不僅可以觸發自訂的異常,還可以觸發系統異常.
RAISE_APPLICATION_ERROR(error_number,message[,true,false]) 用於拋出一個異常,並給異常賦錯誤號碼(預設為+1),錯誤資訊(預設為User_Defined_Exception)
錯誤號碼的範圍是-20,000到-20,999。錯誤資訊是文本字串,最多為2048位元組。TRUE,則新錯誤將被添加到已經引發的錯誤清單中。如果keep_errors=FALSE(預設),則新錯誤將替換當前的錯誤清單。
RAISE_APPLICATION_ERROR(-20123,‘Invald product code‘,TRUE);
異常的傳播
PL/SQL程式塊的異常部分包含了程式處理錯誤的代碼,當異常被觸發時,一個異常陷阱就自動發生,程式控制離開執行部分轉入異常處理部分,一旦程式進入異常處理部分就不能再回到同一塊的執行部分。下面是異常部分的一般文法:
EXCEPTION
WHEN exception_name THEN
Code for handing exception_name
[WHEN another_exception THEN
Code for handing another_exception]
[WHEN others THEN
code for handing any other exception.]
WHEN others THEN 必須放在異常處理的最後面,作為預設處理沒有顯示處理的異常,如果當異常發生時,oracle
沒有尋找到相應的WHEN ... THEN語句,就會執行THEN之後的代碼,如果異常處理代碼僅僅只是退出相應的嵌套塊,那麼
程式將繼續執行內部塊END後面的語句,所以預存程序中,如果不想在發生異常後繼續向下執行,加上RETURN很有必要,如果在同一塊內部沒有找到相應的異常,那麼將同一塊內部的WHEN OTHERS THEN.如果在同一塊內也沒有WHEN OTHERS THEN,則Oracle會向上一層尋找異常處理。如果內層進行了異常處理,則不會再向外層尋找異常再次進行處理。
例如
BEGIN DECLARE DEFINED_EXC EXCEPTION; BEGIN RAISE DEFINED_EXC; --觸發異常,控制轉向; EXCEPTION WHEN DEFINED_EXC THEN dbms_output.put_line(‘DEFINED_EXC‘); END; --DEFINED_EXC異常處理後,控制轉到這裡 EXCEPTION WHEN OTHERS THEN --控制不會從DEFINED_EXC異常轉到這裡,因為內層DEFINED_EXC已被處理 END;
Oracle知識分類之異常