驗證 DECLARE GLOBAL TEMPORARY TABLE 在「獨立 SQL 陳述式」與「SQL 預存程序」中建立、插入、查詢的行為差異。
環境:DB2 UDB V9.1
DECLARE GLOBAL TEMPORARY TABLE SESSION.RESULT (
TMP_HYDM VARCHAR(10),
TMP_HYMC VARCHAR(300)
) WITH REPLACE NOT LOGGED;
INSERT INTO SESSION.RESULT
SELECT MLDM, MLMC FROM DM_HY_CY;
SELECT * FROM SESSION.RESULT;
結果:語法執行成功,但查無資料。
原因:CLP 預設自動提交,每條語句執行完即 COMMIT。全域暫存表定義於 SESSION Schema,Commit 瞬間表定義與資料即從記憶體清除,後續 SELECT 看不到表。
CREATE PROCEDURE SP_TEST_TEMP ()
DYNAMIC RESULT SETS 1
LANGUAGE SQL
P1: BEGIN
DECLARE GLOBAL TEMPORARY TABLE SESSION.RESULT (
TMP_HYDM VARCHAR(10),
TMP_HYMC VARCHAR(300)
) WITH REPLACE NOT LOGGED;
INSERT INTO SESSION.RESULT
SELECT MLDM, MLMC FROM DM_HY_CY;
P2: BEGIN
DECLARE CUR_RES CURSOR WITH RETURN FOR
SELECT * FROM SESSION.RESULT;
OPEN CUR_RES;
END P2;
END P1
結果:預存程序執行成功,正確回傳插入的資料。
原因:預存程序執行期間不會隱式 Commit,暫存表生命週期覆蓋整個程序執行期,游標可正常讀取。
| 場景 | 暫存表生命週期 | 可用性 |
|---|---|---|
| 獨立 SQL(自動提交) | 單條語句結束即銷毀 | 無法跨語句使用 |
| 預存程序 / 顯式交易 | 交易結束(Commit/Rollback)前持續存在 | 完整支援跨語句操作 |
SESSION Schema 為 DB2 專屬,物件生命週期綁定「資料庫連線會話」,類比 JSP Session 物件NOT LOGGED 可減少日誌開銷,但無法 Rollback 恢復暫存表資料