DB2 預存程序透過 DECLARE ... HANDLER 機制處理運行時異常,語法結構如下:
DECLARE handler-type HANDLER FOR condition handler-action
核心在於三種 Handler Type,決定異常發生後的控制流走向:
執行完 handler-action 後,程式繼續執行「發生異常的下一條語句」。適用於可預期、可忽略的警告或 NOT FOUND 情境。
執行完 handler-action 後,立即終止預存程序,控制權返回呼叫端。適用於嚴重錯誤,需快速失敗並回報。
在執行 handler-action 之前,先回滾預存程序內已執行的所有 SQL 操作;隨後終止程序並返回呼叫端。適用於需維護交易一致性的關鍵業務邏輯。
DB2 內建三大預定義條件群,涵蓋最常見的異常場景:
| 條件名稱 | 對應 SQLCODE / SQLSTATE | 典型觸發情境 |
|---|---|---|
NOT FOUND |
SQLCODE +100 / SQLSTATE 02000 | SELECT 無資料回傳、游標到達末尾 |
SQLEXCEPTION |
SQLCODE < 0 | 所有執行階段錯誤(語法、約束違反、權限不足等) |
SQLWARNING |
SQLCODE > 0 且 ≠ +100 | 隱式轉型截斷、權限授予已存在等警告 |
若未為 NOT FOUND 或 SQLWARNING 定義 Handler,DB2 會自動忽略並繼續;若未處理 SQLEXCEPTION,程序直接失敗並返回呼叫端。
當預定義條件不足時,可針對特定 SQLSTATE 宣告自訂條件名稱:
DECLARE unique-name CONDITION FOR SQLSTATE 'sqlstate-value';
CREATE PROCEDURE divide (
IN numerator INTEGER,
IN denominator INTEGER,
OUT result INTEGER
)
LANGUAGE SQL
BEGIN
DECLARE overflow CONDITION FOR SQLSTATE '22003'; -- 數值溢位
DECLARE CONTINUE HANDLER FOR overflow
RESIGNAL SQLSTATE '22375'; -- 重新拋出自訂錯誤碼
IF denominator = 0 THEN
SIGNAL overflow; -- 主動觸發自訂條件
ELSE
SET result = numerator / denominator;
END IF;
END
DECLARE sqlcode INTEGER DEFAULT 0;
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET ret = sqlcode;
DECLARE CONTINUE HANDLER FOR SQLWARNING
SET ret = sqlcode;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET ret = sqlcode;
END;
-- 業務邏輯執行後統一檢查
IF sqlcode < 0 OR sqlcode = 100 THEN
SET O_RetCod = RetCode;
SET O_RetMsg = 'CLN02:產品實例關聯客戶過程出錯!';
INSERT INTO LOG.OPER_LOG_TAB(...)
VALUES ('P_DW_CLEAN', 'GLOBAL TEMP', 0, 0, retcode, ...);
RETURN;
ELSE
SET RetCode = 0;
END IF;
BEGIN ... END 區塊第一行即存入區域變數。poGenStatus) 統一回傳執行狀態,便於上層應用統一錯誤處理。BEGIN ... END 區塊定義,範圍視業務需求而定。善用三種 Handler Type、預定義與自訂條件,配合結構化錯誤記錄,即可建立健壯、可維護的 DB2 預存程序異常處理體系。