在MS SQL Server中,我使用全局臨時表來存儲客戶端傳遞的會話相關信息,然後在觸發器中使用該信息。MS SQL Server - 全局臨時表的安全併發使用?
由於同一個全局臨時表可以在不同的會話中使用,並且在我想寫入時可能存在也可能不存在(取決於先前使用過的所有會話是否關閉),我正在做在寫入之前檢查全局臨時表存在的基礎上創建的。
IF OBJECT_ID('tempdb..##VTT_CONTEXT_INFO_USER_TASK') IS NULL
CREATE TABLE ##VTT_CONTEXT_INFO_USER_TASK (
session_id smallint,
login_time datetime,
HstryUserName VDT_USERNAME,
HstryTaskName VDT_TASKNAME,
)
MERGE ##VTT_CONTEXT_INFO_USER_TASK As target
USING (SELECT @@SPID, @HstryUserName, @HstryTaskName) as source (session_id, HstryUserName, HstryTaskName)
ON (target.session_id = source.session_id)
WHEN MATCHED THEN
UPDATE SET HstryUserName = source.HstryUserName, HstryTaskName = source.HstryTaskName
WHEN NOT MATCHED THEN
INSERT VALUES (@@SPID, @LoginTime, source.HstryUserName, source.HstryTaskName);
的問題是,我的檢查表存在和MERGE
語句之間,SQL Server可能會刪除臨時表,如果它是使用它發生之前的所有會話中,準確的情況下關閉(這實際上發生在我的測試中)。
是否有關於如何避免這種併發問題最佳做法是,一個表沒有檢查它的存在和它的後續使用之間下降了嗎?
感謝您的快速回答!雖然我承認我沒有考慮過永久代碼和臨時共享存儲概念,並且您給了我一些想法,但我確實有理由選擇使用全局臨時表: - 在我的工作中,我可以自由使用臨時表,但創建真正的表必須經歷一個不同的,正式的官僚過程;我儘量避免這種情況。 - 通過使用臨時表,我得到了SQL Server在我沒有會話使用它的情況下將其刪除的優勢。真正的桌子只會留在那裏並繼續增長。 –
@loadH。 。 。哦,唉,官僚作風和奇怪的扭曲,讓事情真正完成。我完全理解。即便如此,也許有可能在一些啓動操作中創建全局臨時表,因此它可用於觸發器。我不喜歡嘗試在觸發器中創建表的想法。 –