我一直未能找到答案。假設我有如下表/查詢:避免在SQL Server中插入重複記錄
表:
create table ##table
(
column1 int,
column2 nvarchar(max)
)
(條件將更爲複雜的真實的生活場景)查詢:
declare @shouldInsert bit
set @shouldInsert = case when exists(
select *
from ##table
where column2 = 'test') then 1 else 0 end
--Exaggerating a possible delay:
waitfor delay '00:00:10'
if(@shouldInsert = 0)
insert into ##table
values(1, 'test')
如果我運行這個同時兩次查詢那麼它易於插入重複記錄(enforsing唯一約束是不可能的,因爲現實生活條件比桌子對面那個單純的「列1」獨特性更多地參與)
我看到了兩個可能的解決方案:
我運行序列化模式中,兩個併發事務,但它會創建一個死鎖(先選擇一個共享鎖,然後X鎖在插入 - 死鎖)。
在SELECT語句中我使用查詢提示用(更新TABLOCK),這將有效的X型鎖整個表,但它會防止讀取數據(這是我想避免)其他交易
哪個更可以接受嗎?有第三種解決方案嗎?
謝謝。
你不能只使用左加入插入##表 SELECT t.col1,t.col2 FROM(SELECT 1 as col1, 'test'as col2)t LEFT JOIN ## table temp ON t.col1 = temp.col1 WHERE temp.col1 IS NULL'? – lad2025
您是否考慮將shouldInsert測試和實際插入組合到單個SQL語句中。 「插入##表格(選擇1,'測試'從雙不存在...' –
我想選擇第二種解決方案,但使用INSERT ... SELECT ... WHERE NOT EXISTS'語法和子查詢中的鎖定提示。我不希望併發性成爲一個問題,除非你有一個非常高的插入速率,假設列2上有一個唯一的索引。 –