在 DB2 SQL PL 中,SELECT INTO 未查到資料會拋出 NOT FOUND 異常,並將 SQLCODE 設為 +100。若未妥善處理,程式將異常終止。本文詳細解析 SQLCODE 100 的行為特性、DECLARE CONTINUE HANDLER 異常捕獲模式與 IF SQLCODE = 100 直接判斷模式,並揭示「處理器內部 SQL 執行成功會重置 SQLCODE 為 0」的關鍵陷阱,提供最佳實務範本。
DECLARE sqlcode INTEGER DEFAULT 0;
DECLARE classCode VARCHAR(40);
SELECT app_class_code INTO classCode
FROM kf_app_class
WHERE app_name = '無效記錄';
SET sql_code = sqlcode; -- 若無資料,sqlcode = 100;有資料則 = 0
SELECT INTO 回傳 0 列 → SQLCODE = +100(NOT FOUND)。SELECT INTO 回傳 ≥1 列 → SQLCODE = 0(成功)。BEGIN
DECLARE CONTINUE HANDLER FOR NOT FOUND
BEGIN
SET sql_code = sqlcode; -- 此處 sqlcode = 100
-- 若此處再執行一次 SET sql_code = sqlcode;
-- 則 sqlcode 已變為 0(因上一條 SET 成功)
END;
SELECT ... INTO ...; -- 觸發 NOT FOUND
SET sql_code = sqlcode; -- 返回主程式後,sqlcode 又變 0 了!
END;
結論:在 HANDLER 內立即將 SQLCODE 存入變數,且勿在 HANDLER 內執行其他成功 SQL,否則會丟失 100 碼。
BEGIN
DECLARE CONTINUE HANDLER FOR NOT FOUND
BEGIN
-- 異常處理邏輯:記錄日誌、設定旗標、預設值等
SET v_not_found = 1;
SET v_class_code = 'DEFAULT';
END;
SELECT app_class_code INTO v_class_code
FROM kf_app_class
WHERE app_name = '無效記錄';
-- 若觸發 NOT FOUND,v_not_found=1、v_class_code='DEFAULT'
-- 否則 v_not_found=0、v_class_code=查詢結果
END;
BEGIN
SELECT app_class_code INTO v_class_code
FROM kf_app_class
WHERE app_name = '無效記錄';
IF SQLCODE = 100 THEN
-- 異常處理邏輯
SET v_not_found = 1;
SET v_class_code = 'DEFAULT';
END IF;
END;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_not_found = 1;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
v_sqlcode = DB2_RETURNED_SQLCODE,
v_msg = MESSAGE_TEXT;
-- 記錄錯誤日誌
CALL log_error(v_sqlcode, v_msg);
END;
IF SQLCODE = 100 即時判斷,語意最清晰。CONTINUE HANDLER FOR NOT FOUND,但嚴禁在 HANDLER 內執行額外 SQL(除非先備份 SQLCODE)。SET v_not_found = 0),避免殘留值誤判。DB2 的 SQLCODE = 100 機制雖簡單,但「成功 SQL 重置 SQLCODE」特性極易造成 Bug。掌握兩種處理模式適用場景、避開 HANDLER 陷阱,即能編寫健壯的 SQL PL 程式。