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

SQL Server 全域暫存表 (##Table) 生命週期管理:啟動預存程序實現永久存活

     編輯:關於SqlServer

全域暫存表 (##Table) 生命週期綁定建立會話 (Session),會話結束即自動刪除。若需跨會話、跨重啟永久存在的共享暫存表,可透過 啟動預存程序 (Startup Stored Procedure) 在 SQL Server 啟動時自動建立,並由引擎維護參考計數防止自動清除。本文提供完整建立步驟、驗證方法與適用場景。

問題背景

  • 一般 ##GlobalTemp:建立會話結束 → 自動刪除,其他會話查詢會報錯「物件不存在」。
  • 需求:應用程式啟動前即存在、任何會話皆可存取、重啟 SQL 後自動重建、除非顯式 DROP 否不消失。

解決方案:啟動預存程序 + master 資料庫

USE MASTER;
GO

IF OBJECT_ID('DBO.SP_GLOBALS') IS NOT NULL
    DROP PROC DBO.SP_GLOBALS;
GO

CREATE PROC DBO.SP_GLOBALS
AS
BEGIN
    SET NOCOUNT ON;
    -- 建立全域暫存表,主鍵確保唯一性
    CREATE TABLE ##GLOBALS (
        ID VARCHAR(36) NOT NULL PRIMARY KEY,  -- 可存 GUID
        VALUE VARCHAR(500)                    -- 應用層序列化物件/JSON
    );
END;
GO

-- 標記為啟動預存程序
EXEC SP_PROCOPTION 'DBO.SP_GLOBALS', 'STARTUP', 'TRUE';
GO

運作機制

  1. SQL Server 啟動 → 執行所有標記 STARTUP = TRUE 的預存程序 (在 master 內建立)。
  2. SP_GLOBALS 建立 ##GLOBALS,引擎為啟動程序建立的全域暫存表維護 參考計數器 > 0。
  3. 參考計數器 > 0 → 不會被自動清除,即使無作用中會話參考。
  4. 任何會話皆可讀寫 ##GLOBALS,如應用設定快取、跨 Session 旗標、單一值狀態共享。
  5. 僅 DROP TABLE ##GLOBALS 或重新執行啟動程序 (重啟 SQL) 會重建。

驗證步驟

-- 1. 重啟 SQL Server 服務 (或手動執行 EXEC SP_GLOBALS)
-- 2. 任意會話查詢
SELECT * FROM TEMPDB.INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '##GLOBALS';
-- 3. 讀寫測試
INSERT INTO ##GLOBALS VALUES (NEWID(), 'TestValue');
SELECT * FROM ##GLOBALS;

適用場景與限制

適用不適用 / 注意
應用設定快取 (少量、頻繁讀取)大量資料 → 應用一般表 + 索引
跨 Session 旗標/鎖狀態需交易一致性 → 一般表 + 明確交易
單一值狀態共享 (如排程最後執行時間)高併發寫入 → 考慮 SEQUENCE / IDENTITY 表
開發/測試環境快速原型生產環境核心業務 → 正式表設計

替代方案比較

  • 一般表 (永久表):完整 ACID、支援索引/統計資訊、需管理清理策略。
  • 記憶體最佳化表 (Hekaton):極高效能、需 SQL 2014+、持久化選項可選。
  • 應用層快取 (Redis/Memcached):跨伺服器共享、需額外基建、序列化開銷。
  • ##GlobalTemp + 啟動程序:零額外物件、自動重建、T-SQL 原生存取、適合輕量共享狀態。

安全性提醒

##GLOBALS 任何擁有 TEMPDB INSERT/UPDATE/DELETE 權限的登入皆可存取。生產環境建議:

  • 建立封裝預存程序 SP_GetGlobal/SP_SetGlobal 控制存取。
  • 僅授與應用帳號 EXECUTE 封裝程序權限,不直接授與表權限。
  • 敏感資料勿存放於全域暫存表。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved