Sql-Server
使用 SET @Variable = Field= @Variable + 1 在堆上出現意外更新結果,使用聚集索引修復
我只是想了解為什麼會發生這種情況,而我的Google搜尋失敗了。我們使用的是 SQL Server 2016 SP1。
情況如下:供應商表通過跟踪每個表的目前值來管理 ID。如果您正在執行插入,則可以呼叫一個函式來返回一個 ID 塊。
所以我們通過使用從真實表中選擇來設置一個臨時表
select into
(我們正在複製一組數據以使用不同的屬性集重新插入)。然後我們呼叫該函式並獲取記錄數的新 id(它只返回最大 ID,所以我們做一些數學運算來獲取下一個 id)。
然後我們像這樣更新表:
update #temp set @nextId = Id = @nextId + 1
期望它將為每條記錄增加一併設置ID。
相反,為每 4 條記錄設置相同的 ID,然後它會增加,接下來的 4 條獲得下一個 id,等等。為什麼每 4 條記錄?什麼地方出了錯?
更有趣的是,如果我們在表上放置一個聚集索引,一切都會正常工作。
我確定這與表格堆有關……但不知道為什麼。
該聲明的文件
UPDATE
說(強調添加):在 UPDATE 語句中可以使用變數名來顯示受影響的舊值和新值,但只有在 UPDATE 語句影響單個記錄時才應使用該變數名。
有些人試圖通過對其使用施加越來越大的限制來使這種“古怪的更新”技術可靠地用於多行。事實仍然是,這依賴於觀察到的效果和未記錄的行為,所以你不應該期望它一般工作,或者在未來繼續“工作”。
如果沒有重現腳本或執行計劃,我無法確切地說出您的情況“出了什麼問題”,但最終這並不重要。如果被迫猜測,我會說您的更新在 DOP 4 處執行,並且四個執行緒同時讀取相同的變數值。
建議您改用可靠的解決方案,例如
ROW_NUMBER
( docs )、IDENTITY
function或sequence。