Insert
插入時如何避免主鍵衝突
我有一個從原始碼插入目標表的程式碼,但有時我們會遇到死鎖。
由於死鎖,我必須再次重新執行此程式碼。
當我重新執行時,我最終違反了主鍵。因此,我想添加一個檢查以僅插入那些不存在的行。
有人可以幫我解決這個問題嗎?
declare @batchSize int = 1000 INSERT INTO [dbo].[Destinationtable] ([PacketId] ,[DeviceId] ,[PacketDate] ,[PacketNumber] ,[Processed] ,[CreateDate] ,[NewReadingId]) SELECT top (@batchSize) [PacketId] ,[DeviceId] ,[PacketDate] ,[PacketNumber] ,[Processed] ,[CreateDate] ,newid() FROM [dbo].[SourceTable] where Processed is null order by CreateDate
死鎖後執行時出現錯誤消息
違反 PRIMARY KEY 約束“PK_packetid”。無法在對象“dbo.destinationtable”中插入重複鍵。重複鍵值為(1234567)。
使用不存在
declare @batchSize int = 1000 INSERT INTO [dbo].[Destinationtable] ([PacketId] ,[DeviceId] ,[PacketDate] ,[PacketNumber] ,[Processed] ,[CreateDate] ,[NewReadingId]) SELECT top (@batchSize) [PacketId] ,[DeviceId] ,[PacketDate] ,[PacketNumber] ,[Processed] ,[CreateDate] ,newid() FROM [dbo].[SourceTable] where Processed is null and not exists (select 1 from [Destinationtable] where [PacketId] = [SourceTable].[PacketId]) order by CreateDate
我懷疑插入數據和更新處理的事務有問題,它們應該是原子的。發生錯誤時,您應該回滾事務並處於安全的基礎上,以便您可以重新啟動事務。
但是,您可以嘗試 MERGE:
MERGE [dbo].[Destinationtable] as x USING ( SELECT top (@batchSize) [PacketId] ,[DeviceId] ,[PacketDate] ,[PacketNumber] ,[Processed] ,[CreateDate] ,newid() FROM [dbo].[SourceTable] where Processed is null order by CreateDate ) y ON x.<key> = <y.key> WHEN NOT MATCHED THEN INSERT (<columns>) VALUES (...);