SQL Server:Join+Insert Where Not Exists/Not In插入主键重复报错排查
解决SQL插入主键重复的问题
兄弟,你遇到的Msg 2627错误就是典型的主键冲突——你要插入的记录里,有部分AppID已经存在于目标表dbo.tblHQTRR_BusiRisk中了,而你的现有插入语句没正确过滤掉这些重复项。
我先帮你分析可能的问题,再给你几个靠谱的写法:
一、你的语句可能犯的错
大概率是你要么没对两张源表的合并数据做去重过滤,要么过滤逻辑写得不对:
- 比如你可能分别对两张表写了插入语句,但只过滤了其中一张表的重复;
- 或者用了
EXISTS而非NOT EXISTS,反而把已存在的记录插进去了; - 甚至可能源表本身就有重复的
AppID,哪怕目标表没有,插入时也会因为源表内部重复触发主键冲突。
二、正确的插入写法
方法1:用NOT EXISTS过滤重复(最常用)
先把两张源表的数据合并,再筛选出目标表中不存在的AppID,然后插入:
INSERT INTO dbo.tblHQTRR_BusiRisk (AppID, [字段1], [字段2], ...) SELECT AppID, [字段1], [字段2], ... FROM ( -- 合并两张源表的数据,用UNION ALL效率更高(如果源表本身无重复的话) SELECT AppID, [字段1], [字段2], ... FROM 你的第一张表 UNION ALL SELECT AppID, [字段1], [字段2], ... FROM 你的第二张表 ) AS SourceData WHERE NOT EXISTS ( -- 检查目标表是否已有该AppID SELECT 1 FROM dbo.tblHQTRR_BusiRisk t WHERE t.AppID = SourceData.AppID );
方法2:用LEFT JOIN + IS NULL过滤
逻辑和上面一致,只是用左连接的方式筛选无匹配的记录:
INSERT INTO dbo.tblHQTRR_BusiRisk (AppID, [字段1], [字段2], ...) SELECT s.AppID, s.[字段1], s.[字段2], ... FROM ( SELECT AppID, [字段1], [字段2], ... FROM 你的第一张表 UNION ALL SELECT AppID, [字段1], [字段2], ... FROM 你的第二张表 ) AS s LEFT JOIN dbo.tblHQTRR_BusiRisk t ON s.AppID = t.AppID -- 只保留目标表中没有匹配的记录 WHERE t.AppID IS NULL;
三、额外注意事项
如果你的两张源表内部本身就有重复的AppID,哪怕目标表没有,插入时也会报错,这时候需要先给源表去重:
INSERT INTO dbo.tblHQTRR_BusiRisk (AppID, [字段1], [字段2], ...) -- 用DISTINCT去重,或者用GROUP BY/ROW_NUMBER()更精准地选择记录 SELECT DISTINCT AppID, [字段1], [字段2], ... FROM ( SELECT AppID, [字段1], [字段2], ... FROM 你的第一张表 UNION ALL SELECT AppID, [字段1], [字段2], ... FROM 你的第二张表 ) AS SourceData WHERE NOT EXISTS ( SELECT 1 FROM dbo.tblHQTRR_BusiRisk t WHERE t.AppID = SourceData.AppID );
如果源表重复的AppID对应不同的其他字段,你可能需要用ROW_NUMBER()来指定取哪一条(比如最新的),这个可以根据你的业务需求调整。
内容的提问来源于stack exchange,提问作者HeatherD
相关产品推荐
相关产品推荐

