2010-10-08 149 views
2

我有一個可以在所有的會話訪問的##臺,但有時我得到錯誤全局臨時表

已經有一個數據庫名爲 「##表」對象。

爲什麼以及如何解決它。

回答

5

發現一個有趣的參考here

全局臨時表操作很像局部臨時表;它們是在tempdb中創建的,並且比永久表導致的鎖定和日誌記錄更少。但是,它們對所有會話均可見,直到創建會話超出範圍(並且全局## temp表不再被其他會話引用)。如果兩個不同的會話嘗試上面的代碼,如果第一個是仍處於活動狀態,而第二個將獲得以下信息:

服務器:消息2714,級別16,狀態6,第1行 已存在名爲對象「 ##人'在數據庫中。

我還沒有看到使用全局##臨時表的有效理由。如果數據需要堅持到多個用戶,那麼至少對我來說,使用永久表更有意義。通過在自動啓動過程中創建一個全局的## temp表,可以使其更具永久性,但我仍然無法看到這比永久表更有優勢。使用永久性表格,您可以拒絕權限;您無法從全局##臨時表中拒絕用戶。

+1

RE:「我還沒有看到使用全局##臨時表的有效理由」當我想要使用全局臨時表能夠創造動態SQL中的表並在外部範圍中訪問它。順便說一下,這篇文章傳播了一個古老的神話,即表變量在內存和光盤上的#temp表。在這方面,兩者之間確實沒有多少(任何?)區別。 – 2010-10-08 19:16:27

+2

我認爲不包括第二段,因爲它與問題沒有直接關係。第一段確實討論了Jeevan描述的確切問題。 – 2010-10-08 19:48:27

3
There is already an object named '##table' in the database. 

如果你正在做CREATE TABLE語句這顯然不能爲「##表」已存在於數據庫中,您通常會得到這個錯誤。

在我看來,也許在代碼中的某個時刻,這個全局表的CREATE TABLE邏輯會再次被調用,導致這個錯誤。

是否有導致此錯誤的確切語句的詳細信息?

2

所以爲什麼部分已經回答了,這裏是如何解決它:

做一次檢查,看看是否臨時表之前創建它的存在:

if object_id('tempdb..##table') is null begin 
     --create table ##table... 
    end 

我發現了一個很有趣的帖子關於如何檢查從谷歌搜索臨時表的存在http://sqlservercodebook.blogspot.com/2008/03/check-if-temporary-table-exists.html

+0

這是線程安全的嗎?當其他會話正在嘗試執行相同的操作時,如何在第一個會話創建之前創建該表時避免競爭條件? – alpav 2014-02-18 19:18:06

+0

@alpav它不會避免競爭條件,所以如果兩個線程同時創建臨時表,其中一個將失敗。 – 2014-02-28 22:27:41