我尝试使用 T-SQL 的 MERGE 语句插入许多记录,但当源表中存在重复记录时,我的查询无法 INSERT。失败的原因是:
- 目标表有一个基于两列的主键
- 源表可能包含违反目标表主键约束的重复记录(抛出“违反主键约束”)
我正在寻找一种方法来更改 MERGE 语句,以便它忽略源表中的重复记录和/或尝试/捕获 INSERT 语句以捕获可能发生的异常(即,所有其他 INSERT 语句都将运行,无论可能会出现一些坏鸡蛋)-或者,也许有更好的方法来解决这个问题?
这是我试图解释的查询示例。下面的示例将向临时表添加 100k 记录,然后尝试将这些记录插入目标表 -
EDIT在我原来的帖子中,我只在示例表中包含了两个字段,这让朋友们可以提供不同的解决方案,以避免 MERGE 语句中的重复。我应该提到,在我的实际问题中,表有 15 个字段,而在这 15 个字段中,其中两个字段是聚集主键。因此 DISTINCT 关键字不起作用,因为我需要选择所有 15 个字段并忽略基于其中两个字段的重复项。
我更新了下面的查询,添加了一个字段 col4。我需要在 MERGE 中包含 col4,但我只需要确保只有 col2 和 col3 是唯一的。
-- Create the source table
CREATE TABLE #tmp (
col2 datetime NOT NULL,
col3 int NOT NULL,
col4 int
)
GO
-- Add a bunch of test data to the source table
-- For testing purposes, allow duplicate records to be added to this table
DECLARE @loopCount int = 100000
DECLARE @loopCounter int = 0
DECLARE @randDateOffset int
DECLARE @col2 datetime
DECLARE @col3 int
DECLARE @col4 int
WHILE (@loopCounter) < @loopCount
BEGIN
SET @randDateOffset = RAND() * 100000
SET @col2 = DATEADD(MI,@randDateOffset,GETDATE())
SET @col3 = RAND() * 1000
SET @col4 = RAND() * 10
INSERT INTO #tmp
(col2,col3,col4)
VALUES
(@col2,@col3,@col4);
SET @loopCounter = @loopCounter + 1
END
-- Insert the source data into the target table
-- How do we make sure we don't attempt to INSERT a duplicate record? Or how can we
-- catch exceptions? Or?
MERGE INTO dbo.tbl1 AS tbl
USING (SELECT * FROM #tmp) AS src
ON (tbl.col2 = src.col2 AND tbl.col3 = src.col3)
WHEN NOT MATCHED THEN
INSERT (col2,col3,col4)
VALUES (src.col2,src.col3,src.col4);
GO