SQLCODE 與 SQLERRM 是 PL/SQL 異常處理塊中**僅可在 `WHEN OTHERS` 或未命名異常處理器中調用**的內置函數,分別返回 Oracle 錯誤碼(數字)與錯誤消息文本(最多 512 字節)。
BEGIN
-- 業務邏輯
NULL;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
-- 處理已知異常
log_error('唯一約束違反', SQLCODE, SQLERRM);
WHEN OTHERS THEN
-- 捕獲所有其他異常,必須放在最後
log_error('未預期錯誤', SQLCODE, SQLERRM);
-- 可選:重新拋出或包裝為自定義異常
RAISE_APPLICATION_ERROR(-20001, '系統錯誤: ' || SQLERRM);
END;
| 特性 | SQLCODE | SQLERRM |
|---|---|---|
| 返回類型 | NUMBER | VARCHAR2 |
| 成功時值 | 0 | 'ORA-0000: normal, successful completion' |
| 異常時值 | 負數(如 -1, -1403) | 完整錯誤文本(含 ORA- 前綴) |
| 可接受參數 | 無 | 可傳入錯誤碼:SQLERRM(-1403) 返回 'ORA-01403: no data found' |
| 調用上下文 | 僅異常處理器中 | 僅異常處理器中(或傳入錯誤碼時可在任意處) |
WHEN OTHERS THEN
INSERT INTO error_log (err_time, err_code, err_msg, err_stack, call_stack)
VALUES (SYSTIMESTAMP, SQLCODE, SQLERRM, DBMS_UTILITY.FORMAT_ERROR_STACK, DBMS_UTILITY.FORMAT_CALL_STACK);
BEGIN
SELECT ... INTO v_var FROM ... WHERE ...;
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- SQLCODE = +100(正數),SQLERRM = 'ORA-01403: no data found'
v_var := DEFAULT_VAL;
WHEN OTHERS THEN
-- 處理真正的錯誤
RAISE;
END;
注意:`NO_DATA_FOUND` 的 SQLCODE 為 **+100**(正數),而非負數,`WHEN OTHERS` 不會捕獲它。
e_salary_too_high EXCEPTION;
PRAGMA EXCEPTION_INIT(e_salary_too_high, -20101);
BEGIN
IF v_sal > 100000 THEN RAISE e_salary_too_high; END IF;
EXCEPTION
WHEN e_salary_too_high THEN
-- SQLCODE = -20101, SQLERRM = 'ORA-20101: User-Defined Exception'
log_biz_error('薪資超標', SQLCODE, SQLERRM);
END;
熟練掌握 `SQLCODE`/`SQLERRM` 的行為邊界,是編寫健壯 PL/SQL 異常處理體系的核心技能。