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

DB2 已聲明全局臨時表 (DGTT) 進階應用:跨會話/存儲過程共享實戰模式

     編輯:DB2 教學

核心概念回顧

已聲明全局臨時表 (DGTT) 是 DB2 V7.2+ 引入的會話級私有表,特性:

  • 數據僅在當前會話可見,斷開自動清理
  • 定義存儲於 SESSION 模式,物理數據駐留於用戶臨時表空間
  • 不記錄重做日誌 (NOT LOGGED),極高寫入性能
  • 支持 ON COMMIT PRESERVE/DELETE ROWS 控制提交行為

前置準備:創建用戶臨時表空間

-- 自動管理 (SMS) - 開發/測試環境
CREATE USER TEMPORARY TABLESPACE USRTEMP1 MANAGED BY SYSTEM USING ('usr_temp1');

-- 數據庫管理 (DMS) - 生產環境推薦,性能更優
CREATE USER TEMPORARY TABLESPACE USRTEMP1 MANAGED BY DATABASE 
  USING (FILE '/db2/temp/usr_temp1' 500M) 
  EXTENTSIZE 32 PREFETCHSIZE 32 BUFFERPOOL IBMDEFAULTBP;

核心難題:跨存儲過程/應用共享 DGTT

直接在多個存儲過程中 DECLARE GLOBAL TEMPORARY TABLE 同名表會報錯 SQL0601N。解決關鍵:在調用鏈入口處 (應用/首個過程) 聲明一次,後續過程直接引用 SESSION.TABLE_NAME 無需再次聲明。

模式一:應用程序主導共享 (CLP/驅動程序聲明)

-- 1. 應用連接後首聲明
CONNECT TO SAMPLE;
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP_EMP 
  LIKE EMPLOYEE 
  ON COMMIT PRESERVE ROWS 
  NOT LOGGED;

-- 2. 創建引用該 DGTT 的存儲過程 (體內無聲明)
CREATE PROCEDURE PROC_PROCESS_TEMP_EMP() 
RESULT SETS 1
LANGUAGE SQL
BEGIN
  DECLARE C1 CURSOR WITH RETURN TO CLIENT FOR
    SELECT EMPNO, FIRSTNME, LASTNAME 
    FROM SESSION.TEMP_EMP 
    FETCH FIRST 10 ROWS ONLY;
  OPEN C1;
END;

-- 3. 應用填充數據並調用
INSERT INTO SESSION.TEMP_EMP SELECT * FROM EMPLOYEE WHERE WORKDEPT = 'A00';
CALL PROC_PROCESS_TEMP_EMP();  -- 成功返回游標結果集

模式二:存儲過程鏈式調用共享 (封裝聲明/銷毀)

適用於:ETL 流程中多個過程協作處理同一中間結果集。

基礎設施過程

-- 初始化過程:集中管理 DDL,便於變更控制
CREATE PROCEDURE INIT_TEMP_WORK_TABLE()
SPECIFIC INIT_TEMP_WORK_TABLE
LANGUAGE SQL
BEGIN
  DECLARE GLOBAL TEMPORARY TABLE SESSION.WORK_DATA (
    BATCH_ID     INT,
    SRC_SYSTEM   VARCHAR(20),
    PAYLOAD      BLOB(1M),
    PROC_STAGE   SMALLINT DEFAULT 0
  ) ON COMMIT PRESERVE ROWS NOT LOGGED;
END;

-- 清理過程:連接池環境必須顯式調用,防止連接復用導致殘留
CREATE PROCEDURE CLEANUP_TEMP_WORK_TABLE()
SPECIFIC CLEANUP_TEMP_WORK_TABLE
LANGUAGE SQL
BEGIN
  DECLARE CONTINUE HANDLER FOR SQLSTATE '42704' BEGIN END; -- 忽略不存在錯誤
  DROP TABLE SESSION.WORK_DATA;
END;

業務協作過程鏈

-- 過程 1: 數據抽取入臨時表
CREATE PROCEDURE ETL_EXTRACT_STAGE(IN p_batch_id INT)
LANGUAGE SQL
BEGIN
  CALL INIT_TEMP_WORK_TABLE();  -- 確保表存在
  INSERT INTO SESSION.WORK_DATA (BATCH_ID, SRC_SYSTEM, PAYLOAD, PROC_STAGE)
  SELECT p_batch_id, 'CRM', CUSTOMER_DATA, 10 
  FROM CRM.STAGING_TABLE 
  WHERE BATCH_ID = p_batch_id;
END;

-- 過程 2: 轉換清洗
CREATE PROCEDURE ETL_TRANSFORM_STAGE(IN p_batch_id INT)
LANGUAGE SQL
BEGIN
  -- 直接引用 SESSION.WORK_DATA 無需聲明
  UPDATE SESSION.WORK_DATA 
  SET PAYLOAD = TRANSFORM_BLOB(PAYLOAD), PROC_STAGE = 20
  WHERE BATCH_ID = p_batch_id AND PROC_STAGE = 10;
END;

-- 過程 3: 目標裝載
CREATE PROCEDURE ETL_LOAD_STAGE(IN p_batch_id INT)
LANGUAGE SQL
BEGIN
  DECLARE C1 CURSOR FOR 
    SELECT PAYLOAD FROM SESSION.WORK_DATA 
    WHERE BATCH_ID = p_batch_id AND PROC_STAGE = 20;
  -- 裝載邏輯...
  CALL CLEANUP_TEMP_WORK_TABLE(); -- 鏈路結束清理
END;

-- 主協調過程
CREATE PROCEDURE ETL_MASTER_FLOW(IN p_batch_id INT)
LANGUAGE SQL
BEGIN
  CALL ETL_EXTRACT_STAGE(p_batch_id);
  CALL ETL_TRANSFORM_STAGE(p_batch_id);
  CALL ETL_LOAD_STAGE(p_batch_id);
END;

Development Center 圖形化開發最佳實踐

  1. 項目結構:建立 TempTable_Infrastructure 文件夾存放 INIT_*/CLEANUP_* 過程
  2. 版本控制:DGTT DDL 僅存在於 INIT_* 過程中,結構變更單點維護
  3. 部署腳本:導出含 INIT/CLEANUP 及所有業務過程的部署腳本,保證依賴順序

關鍵限制與避坑指南

⚠️ 限制/陷阱影響規避方案
連接池環境不清理連接復用時 DGTT 殘留導致數據洩露/主鍵衝突強制在業務邏輯結束調用 CLEANUP_*,或使用 ON COMMIT DELETE ROWS
DGTT 無統計信息優化器使用默認估算,可能產生劣質計劃關鍵路徑調用 RUNSTATS ON TABLE SESSION.TNAME WITH DISTRIBUTION
不支持外鍵/觸發器/RI無法聲明引用完整性約束應用層邏輯保證數據質量
大對象 (LOB) 列限制早期版本不支持 LOB,V9.7+ 已支持確認 DB2 版本兼容性
並發會話隔離同名 DGTT 互不干擾,但臨時表空間共享監控臨時表空間使用率,防止單會話佔滿

性能優化提示

  • 索引策略:DGTT 支持 CREATE INDEX,大數據量連接查詢前建立索引
  • 物化視圖替代:複雜多表連接結果物化到 DGTT,供下游多次消費
  • 並行度控制:填充 DGTT 時設置 SET CURRENT DEGREE = 'ANY' 利用並行插入

總結

DGTT 共享模式的核心在於 「聲明一次,多方引用」。通過封裝初始化/清理過程,構建標準化的臨時表基礎設施,可實現:

  • 複雜 ETL 流程的中間結果高效流轉
  • 應用與存儲過程、存儲過程間的零拷貝數據交換
  • DDL 變更的集中管控與版本管理

掌握此模式,將顯著提升 DB2 應用開發的靈活性與性能表現。

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