已聲明全局臨時表 (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;
直接在多個存儲過程中 DECLARE GLOBAL TEMPORARY TABLE 同名表會報錯 SQL0601N。解決關鍵:在調用鏈入口處 (應用/首個過程) 聲明一次,後續過程直接引用 SESSION.TABLE_NAME 無需再次聲明。
-- 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;
TempTable_Infrastructure 文件夾存放 INIT_*/CLEANUP_* 過程INIT_* 過程中,結構變更單點維護INIT/CLEANUP 及所有業務過程的部署腳本,保證依賴順序| ⚠️ 限制/陷阱 | 影響 | 規避方案 |
|---|---|---|
| 連接池環境不清理 | 連接復用時 DGTT 殘留導致數據洩露/主鍵衝突 | 強制在業務邏輯結束調用 CLEANUP_*,或使用 ON COMMIT DELETE ROWS |
| DGTT 無統計信息 | 優化器使用默認估算,可能產生劣質計劃 | 關鍵路徑調用 RUNSTATS ON TABLE SESSION.TNAME WITH DISTRIBUTION |
| 不支持外鍵/觸發器/RI | 無法聲明引用完整性約束 | 應用層邏輯保證數據質量 |
| 大對象 (LOB) 列限制 | 早期版本不支持 LOB,V9.7+ 已支持 | 確認 DB2 版本兼容性 |
| 並發會話隔離 | 同名 DGTT 互不干擾,但臨時表空間共享 | 監控臨時表空間使用率,防止單會話佔滿 |
CREATE INDEX,大數據量連接查詢前建立索引SET CURRENT DEGREE = 'ANY' 利用並行插入DGTT 共享模式的核心在於 「聲明一次,多方引用」。通過封裝初始化/清理過程,構建標準化的臨時表基礎設施,可實現:
掌握此模式,將顯著提升 DB2 應用開發的靈活性與性能表現。