答案是肯定的。DB2 支援可更新游標搭配定位更新機制,允許在游標定位的當前資料列上執行 UPDATE 或 DELETE,且不影響游標位置與後續 FETCH。
適用於 SQL PL 存儲程序、觸發器、腳本中。
DECLARE c1 CURSOR FOR
SELECT id, name FROM t2
FOR UPDATE;
OPEN c1;
FETCH c1 INTO v_id, v_name;
WHILE SQLSTATE = '00000' DO
UPDATE t2
SET sname = 'lx_' || sname
WHERE CURRENT OF c1;
FETCH c1 INTO v_id, v_name;
END WHILE;
CLOSE c1;
適用於 C/C++、CLI、JDBC 等應用程式開發介面。
CREATE PROCEDURE KYJT.SP_TESTT ()
SPECIFIC KYJT.SQL060421171925193
LANGUAGE SQL
NOT DETERMINISTIC
CALLED ON NULL INPUT
MODIFIES SQL DATA
INHERIT SPECIAL REGISTERS
BEGIN
DECLARE PNAME VARCHAR(50);
DECLARE PID INT;
DECLARE v_count INT;
DECLARE SQLSTATE CHAR(5);
DECLARE at_end INT DEFAULT 0;
DECLARE not_found CONDITION FOR SQLSTATE '02000';
DECLARE C1 CURSOR FOR
SELECT ID, NAME FROM KYJT.TESTT
FOR UPDATE;
DECLARE CONTINUE HANDLER FOR not_found
SET at_end = 1;
OPEN C1;
INS_LOOP: LOOP
FETCH C1 INTO PID, PNAME;
IF at_end = 1 THEN
LEAVE INS_LOOP;
END IF;
UPDATE KYJT.TESTT A
SET NAME = (SELECT NAME FROM KYJT.TEST B WHERE B.ID = PID)
WHERE CURRENT OF C1;
END LOOP;
CLOSE C1;
END
| 要素 | 說明 |
|---|---|
FOR UPDATE 子句 | 宣告游標為可更新,DB2 會在讀取資料列時加持適當鎖定(通常為 U 鎖升級 X 鎖) |
WHERE CURRENT OF cursor_name | 直接針對游標當前資料列操作,無需再次指定 WHERE 條件,避免鍵值變更導致邏輯錯誤 |
| 同一連線/交易 | 定位更新必須在開啟游標的同一連線、同一交易內執行,共享交易空間與鎖資源 |
| 鎖相容性 | 游標持有的鎖不會阻擋自身發起的定位更新 |
NOT FOUND 處理器 | DB2 使用 SQLSTATE '02000' 表示游標無資料,需自訂條件名稱對應 |
FOR UPDATE 遊標專為此設計。UPDATE(帶 WHERE 條件)。FOR READ ONLY 明確宣告,可更新游標加 FOR UPDATE,語義清晰且助優化器生成最佳計畫。善用可更新游標與定位更新,能編寫出高效能、邏輯清晰的 DB2 程序化程式碼,是進階 DB2 開發者的必備技能。