首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle Developer 異常處理機制全解析:優勢、分類、拋出、傳播與預定義異常速查表

     編輯:Oracle 資料庫基礎

Oracle Developer (PL/SQL) 異常處理機制完善,能將錯誤邏輯與業務邏輯分離,大幅提升程式碼可讀性與維護性。本文系統整理異常處理核心觀念與實戰技巧。

1. 異常處理的優勢

無異常時需逐行檢查錯誤,程式碼混雜難讀:

BEGIN
  SELECT ...; -- check NO_DATA_FOUND
  SELECT ...; -- check NO_DATA_FOUND
  SELECT ...; -- check NO_DATA_FOUND
END;

引入異常處理後:

BEGIN
  SELECT ...;
  SELECT ...;
  SELECT ...;
EXCEPTION
  WHEN NO_DATA_FOUND THEN -- 統一捕獲所有查無資料
    ...
END;

優點: 錯誤處理集中、業務邏輯清晰、可讀性強、易維護。

2. 異常分類

類別來源處理方式
內部異常Oracle 執行期錯誤 (除零、記憶體不足) 或違反規則隱式拋出,可用預定義名稱或 PRAGMA EXCEPTION_INIT 關聯錯誤碼
使用者自定義異常開發者依業務邏輯定義宣告區 EXCEPTION 關鍵字,RAISE 顯式拋出

3. 常用預定義內部異常速查

異常名稱Oracle ErrorSQLCODE觸發情境
NO_DATA_FOUNDORA-01403+100SELECT INTO 無資料
TOO_MANY_ROWSORA-01422-1422SELECT INTO 多筆資料
DUP_VAL_ON_INDEXORA-00001-1唯一索引鍵重複
VALUE_ERRORORA-06502-6502字元轉換/截斷/長度不足
STORAGE_ERRORORA-06500-6500記憶體不足
ZERO_DIVIDEORA-01476-1476除數為零
CASE_NOT_FOUNDORA-06592-6592CASE 無匹配且無 ELSE
CURSOR_ALREADY_OPENORA-06511-6511重複開啟游標
TIMEOUT_ON_RESOURCEORA-00051-51資源等待逾時

未預定義的內部異常可用 OTHERS 捕獲,或 PRAGMA EXCEPTION_INIT(my_exc, -error_code) 關聯自訂名稱。

4. 異常拋出三種方式

  1. PL/SQL 執行引擎隱式拋出: 違反規則/資源錯誤自動觸發。
  2. RAISE 陳述式: RAISE exception_name; 可拋出自定義或預定義異常。
  3. RAISE_APPLICATION_ERROR: RAISE_APPLICATION_ERROR(-20001, 'Custom msg', TRUE/FALSE);
    • 錯誤碼範圍:-20000 ~ -20999。
    • 訊息長度 ≤ 2048 bytes。
    • 第三參數 TRUE 疊加錯誤堆疊,FALSE (預設) 覆蓋。

5. 異常處理區塊語法

EXCEPTION
  WHEN exception_name THEN
    -- 處理碼
  WHEN another_exception THEN
    -- 處理碼
  WHEN OTHERS THEN
    -- 預設處理器 (必須置最後)
    err_code := SQLCODE;
    err_msg  := SUBSTR(SQLERRM, 1, 100);
    INSERT INTO error_log VALUES (err_code, err_msg);
END;

處理完成後控制權返回上層區塊緊接著的陳述式,不會回到拋出點。

6. 異常傳播規則 (關鍵)

  • 執行區拋出: 先找當區塊處理器 → 無則傳播給外層區塊異常區 → 直到最外層或被處理。
  • 宣告區拋出: 立即傳播給外層區塊異常區 (不進入當區塊異常區)。
  • 異常區拋出: 立即傳播給外層區塊異常區 (不進入當區塊其餘異常處理器)。

傳播範例

-- 內層無處理器,外層捕獲
BEGIN
  BEGIN
    RAISE my_exc;
  EXCEPTION
    WHEN OTHERS THEN NULL; -- 若這裡不處理,外層 WHEN OTHERS 會收到
  END;
EXCEPTION
  WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('外層捕獲');
END;

-- 異常區再拋出
BEGIN
  BEGIN
    RAISE exc_a;
  EXCEPTION
    WHEN exc_a THEN RAISE exc_b; -- 立即傳播給外層
    WHEN exc_b THEN NULL;        -- 永遠不會執行
  END;
EXCEPTION
  WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('外層捕獲 exc_b');
END;

7. SQLCODE/SQLERRM 在 OTHERS 中的應用

  • SQLCODE:回傳 Oracle 錯誤碼 (負數),NO_DATA_FOUND 為 +100,自定義異常為 +1。
  • SQLERRM:回傳完整錯誤訊息 (含錯誤碼),長度 ≤ 512 bytes。自定義異常回傳 User-Defined Exception。
  • 無異常時 SQLCODE=0、SQLERRM='ORA-0000: normal, successful completion'。

最外層區塊建議保留 WHEN OTHERS 記錄錯誤日誌,確保無錯誤漏捕。

8. 完整預定義異常表 (補充)

ACCESS_INTO_NULL       ORA-06530  -6530
CASE_NOT_FOUND         ORA-06592  -6592
COLLECTION_IS_NULL     ORA-06531  -6531
CURSOR_ALREADY_OPEN    ORA-06511  -6511
DUP_VAL_ON_INDEX       ORA-00001  -1
INVALID_CURSOR         ORA-01001  -1001
INVALID_NUMBER         ORA-01722  -1722
LOGIN_DENIED           ORA-01017  -1017
NO_DATA_FOUND          ORA-01403  +100
NOT_LOGGED_ON          ORA-01012  -1012
PROGRAM_ERROR          ORA-06501  -6501
ROWTYPE_MISMATCH       ORA-06504  -6504
SELF_IS_NULL           ORA-30625  -30625
STORAGE_ERROR          ORA-06500  -6500
SUBSCRIPT_BEYOND_COUNT ORA-06533  -6533
SUBSCRIPT_OUTSIDE_LIMIT ORA-06532 -6532
SYS_INVALID_ROWID      ORA-01410  -1410
TIMEOUT_ON_RESOURCE    ORA-00051  -51
TOO_MANY_ROWS          ORA-01422  -1422
VALUE_ERROR            ORA-06502  -6502
ZERO_DIVIDE            ORA-01476  -1476
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved