首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 全域暫存表(GTT)完整指南:建立、特性與動態應用實戰

     編輯:Oracle 資料庫相關知識

什麼是全域暫存表?

Global Temporary Table (GTT) 定義永久存在於資料字典,但資料僅在 **會話** 或 **交易** 期間可見。不同會話互不干擾,Commit 或 Session 結束自動清理,無需手動維護,極適合暫存中間運算結果。

兩種保留模式比較

模式語法資料生命週期適用場景
會話級 ON COMMIT PRESERVE ROWS Session 結束才清除 跨多個交易的複雜 ETL、報表暫存
交易級 ON COMMIT DELETE ROWS Commit/Rollback 即清除 單一交易內的中繼運算、暫存參數

建立語法範例

-- 會話級暫存表
CREATE GLOBAL TEMPORARY TABLE gtt_session_data (
    id          NUMBER,
    batch_no    VARCHAR2(30),
    proc_date   DATE
) ON COMMIT PRESERVE ROWS;

-- 交易級暫存表
CREATE GLOBAL TEMPORARY TABLE gtt_txn_data (
    tmp_key     VARCHAR2(50),
    tmp_val     NUMBER
) ON COMMIT DELETE ROWS;

關鍵特性必讀

  • DDL 無法在執行期動態建立:GTT 結構必須預先建立,但可用 EXECUTE IMMEDIATE 動態 DML。
  • 統計資訊共享問題:12c 前預設共享統計,導致執行計劃不準。12c+ 可用 DBMS_STATS.SET_TABLE_PREFS(..., 'GLOBAL_TEMP_TABLE_STATS', 'SESSION') 設定會話級統計。
  • 無 Redo 產生:DML 不產生 Redo Log(Undo 仍有),大幅降低 I/O。
  • 索引、觸發器、外鍵限制:可建索引(同樣為暫存),但**不可建外鍵參考永久表**,也無法分區。

動態應用實戰:PL/SQL 封裝範例

CREATE OR REPLACE PROCEDURE proc_temp_demo (
    p_col1 IN VARCHAR2,
    p_col2 IN VARCHAR2
) AS
    v_cnt NUMBER;
BEGIN
    -- 1. 確保表存在(僅首次執行需建立,實務建議部署腳本預建)
    BEGIN
        EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE gtt_demo (
            col1 VARCHAR2(10), col2 VARCHAR2(10)
        ) ON COMMIT DELETE ROWS';
    EXCEPTION WHEN OTHERS THEN
        IF SQLCODE != -955 THEN RAISE; END IF; -- 忽略 "name already used"
    END;

    -- 2. 插入資料
    EXECUTE IMMEDIATE 'INSERT INTO gtt_demo VALUES (:1, :2)' USING p_col1, p_col2;

    -- 3. 查詢驗證
    EXECUTE IMMEDIATE 'SELECT col1 FROM gtt_demo' INTO v_cnt;
    DBMS_OUTPUT.PUT_LINE('Inserted: ' || v_cnt);

    -- 4. 交易結束自動清除(ON COMMIT DELETE ROWS)
    COMMIT;
END;
/

常見誤區與避坑指南

  1. 誤以為不同 Session 可共享資料:GTT 絕對隔離,若需跨 Session 共享請用永久表 + 批次欄位區分。
  2. 長期持有 Session 導致暫存段膨脹:會話級 GTT 若不 Commit/Close,暫存段持續增長,監控 V$TEMPSEG_USAGE。
  3. 統計資訊缺失導致全表掃描:大量資料場景請在 PL/SQL 內呼叫 DBMS_STATS.GATHER_TABLE_STATS(..., 'GTT_DEMO')。

結語

GTT 是 Oracle 處理暫時性資料的利器,善用 ON COMMIT PRESERVE/DELETE ROWS 搭配 12c+ 會話級統計,能大幅簡化 ETL 與複雜報表邏輯,並降低 Redo/Undo 壓力。

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