2017-04-10 70 views
0

我在存儲過程的代碼如下,運行光標內臨時表:默認名稱主鍵已經存在

IF (OBJECT_ID('tempdb..#newSales','U') IS NOT NULL) 
    DROP TABLE #newSales 

CREATE TABLE #newSales 
(
    AddressId INT NOT NULL, 
    ItemId INT NOT NULL, 
    [Date] DATE NOT NULL, 
    Sale REAL NULL 
) 

/* some code here */ 

ALTER TABLE #newSales 
    ADD PRIMARY KEY CLUSTERED ([AddressId] ASC, [ItemId] ASC, [Date] ASC) 

週期性我得到以下錯誤(名稱每次都是不同):

數據庫中已有一個名爲'PK__#newSale__34CE1EAA297D3472'的對象。

我檢查了類似的問題,但其中大多數都與顯式命名約束。我無法理解這是怎麼發生的,因爲在這種情況下,PK的名字是自動生成的,理論上它必須是唯一的(即使有多個連接調用這個過程)。

什麼是錯誤的根源?

+2

也許兩個線程同時運行代碼。在光標內創建一個表似乎不是一個好主意。 –

+0

據我所知,如果兩個線程正在運行代碼,那麼將同時存在2個相同的臨時表,但自動生成的名稱必須幫助解決這個問題,不是嗎?我只是不知道爲什麼生成的名稱是相同的... 關於遊標中的表格:爲什麼這是一個壞主意?我在哪裏可以讀到它? – STiLeTT

回答

0

您應該避免在併發可能成爲問題的情況下創建臨時表,而應嘗試使用變量表。請嘗試以下操作:

DELCARE @newSales TABLE 
(
    AddressId INT NOT NULL, 
    ItemId INT NOT NULL, 
    [Date] DATE NOT NULL, 
    Sale REAL NULL, 
    PRIMARY KEY CLUSTERED ([AddressId] ASC, [ItemId] ASC, [Date] ASC) 
) 

INSERT INTO @newSales 
SELECT * 
FROM myOtherTables 
... 
+0

我還不確定我的代碼是否同時運行,但即使是這樣,我也不明白爲什麼我應該避免這種情況?感謝您的信息,如果我找不到問題的根源,我會嘗試。我只是不想使用表變量,因爲由於缺乏統計數據,它們在我的情況下非常慢。 – STiLeTT

+0

問題是如果代碼同時運行,第二個將嘗試刪除在第一個線程中創建的表。使用變量表可以防止所有形式的干擾。 – LunarSage

+0

不,第二個代碼不會刪除第一個表,因爲數據庫引擎正在爲每個本地臨時表名添加數字後綴。 ([msdn](https://technet.microsoft.com/en-us/library/ms174979(v = sql.105).aspx#Anchor_2)) – STiLeTT