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

DB2 游標原理與操作全流程:宣告、開啟、擷取、關閉與迴圈控制實戰

     編輯:DB2 教學

游標是將 SQL 結果集(多列)轉為程式可逐列處理的核心機制。本文系統說明 DB2 游標四大操作步驟、SQLCODE/SQLSTATE 迴圈控制技巧、WITH HOLD 持久游標特性,並提供標準範本與常見錯誤避坑指南。

一、游標四大操作步驟

1. 宣告游標 —— 定義查詢,不執行

DECLARE cursor_name CURSOR FOR
    SELECT col1, col2, ...
    FROM table
    WHERE condition
    FOR READ ONLY;  -- 唯讀游標效能較佳,避免鎖升級

2. 開啟游標 —— 執行查詢,建立結果集緩衝區

OPEN cursor_name;
  • 游標進入活動狀態,指標指向結果集第一列之前。
  • 若查詢耗時長,OPEN 階段即會消耗資源。

3. 擷取資料 —— 推進指標、讀取當前列

FETCH cursor_name INTO var1, var2, ...;
  • 每次 FETCH 推進一列,將欄位值存入對應變數。
  • 通常置於迴圈中逐列處理。
  • 進階:FETCH NEXT/FIRST/LAST/PRIOR/ABSOLUTE n/RELATIVE n(捲動游標)。

4. 關閉游標 —— 釋放資源

CLOSE cursor_name;
  • 釋放結果集緩衝區、鎖定資源。
  • 關閉後可再次 OPEN(重新執行查詢)。

二、標準迴圈控制範本

模式 A:SQLCODE 判斷(傳統)

DECLARE sqlcode INTEGER DEFAULT 0;
DECLARE v_col1 TYPE;
DECLARE v_col2 TYPE;

DECLARE c1 CURSOR FOR SELECT col1, col2 FROM t1;
OPEN c1;

FETCH c1 INTO v_col1, v_col2;
WHILE sqlcode = 0 DO
    -- 處理 v_col1, v_col2
    FETCH c1 INTO v_col1, v_col2;
END WHILE;

CLOSE c1;

模式 B:SQLSTATE 判斷(標準化)

DECLARE sqlstate CHAR(5) DEFAULT '00000';
-- ...
FETCH c1 INTO v_col1, v_col2;
WHILE sqlstate = '00000' DO
    -- 處理
    FETCH c1 INTO v_col1, v_col2;
END WHILE;

模式 C:使用者自訂旗標(最穩健)

DECLARE at_end SMALLINT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET at_end = 1;

OPEN c1;
FETCH c1 INTO v_col1, v_col2;
WHILE at_end = 0 DO
    -- 處理
    FETCH c1 INTO v_col1, v_col2;
END WHILE;
CLOSE c1;

三、進階特性

WITH HOLD 游標

DECLARE c1 CURSOR WITH HOLD FOR SELECT ...;
  • COMMIT 後不關閉游標,可跨交易繼續 FETCH。
  • 適用於「逐列處理、每筆獨立 COMMIT」場景(見預存程序游標迴圈文章)。
  • ROLLBACK 仍會關閉游標。

捲動游標

DECLARE c1 SCROLL CURSOR FOR SELECT ...;
  • 支援 FETCH ABSOLUTE 10、FETCH PRIOR 等隨機存取。
  • 需在宣告時指定 SCROLL,資源消耗較大。

四、常見錯誤與避坑

錯誤現象 原因 修正
FETCH 後未檢查狀態直接處理變數最後一次 FETCH 失敗,變數殘留舊值務必在 WHILE 條件或 HANDLER 中判斷
忘記 CLOSE 游標資源洩漏、鎖持有過久在離開範圍前(含例外分支)必呼叫 CLOSE
COMMIT 後續 FETCH 失敗非 WITH HOLD 游標被 COMMIT 關閉宣告時加 WITH HOLD
巢狀迴圈使用同一游標變數內層 CLOSE 影響外層使用不同游標名稱

五、完整最佳實務範本

BEGIN
  DECLARE v_id INTEGER;
  DECLARE v_name VARCHAR(50);
  DECLARE at_end SMALLINT DEFAULT 0;

  DECLARE c1 CURSOR WITH HOLD FOR
    SELECT id, name FROM employees WHERE dept = 'IT' FOR READ ONLY;

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET at_end = 1;

  OPEN c1;
  FETCH c1 INTO v_id, v_name;

  WHILE at_end = 0 DO
    -- 業務邏輯
    CALL process_emp(v_id, v_name);

    -- 若需逐筆 COMMIT
    COMMIT;

    FETCH c1 INTO v_id, v_name;
  END WHILE;

  CLOSE c1;
END;

小結

掌握游標「宣告→開啟→擷取→關閉」標準流程、善用 CONTINUE HANDLER 取代 SQLCODE 判斷、關鍵場景加上 WITH HOLD,即能編寫高可靠、高效能的 DB2 游標程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved