Access执行Insert Into查询时出现键冲突错误的排查求助
主键冲突错误原因及解决办法
错误原因
- 临时表内部存在重复记录:Temp_Day_Table无主键和索引,可能存在多条
(Emp_ID_FK, Time_ID_FK, Day)完全相同的记录。你的左连接逻辑仅过滤掉EMP_TIME中已存在的组合,但临时表内部的重复记录仍会被全部选中插入。插入时这些重复记录触发EMP_TIME的主键约束导致冲突报错;但因主键唯一,最终仅一条能插入成功,所以事后查询看不到重复数据。 - 并发写入冲突(概率较低):若执行插入时,有其他会话同时向EMP_TIME插入相同主键组合的记录,也会触发主键冲突,这类情况多伴随业务并发场景。
解决办法
方法1:先对临时表数据去重再插入
在SELECT语句中加入DISTINCT关键字,过滤Temp_Day_Table内部的重复记录,同时明确只插入EMP_TIME中不存在的条目:
INSERT INTO EMP_TIME ( EMP_ID_FK, TIME_ID_FK, Hours, Date_Time, EMP_TIME_Desc ) SELECT DISTINCT t.Emp_ID_FK, t.Time_ID_FK, t.Hours, t.Day, t.Description FROM Temp_Day_Table t LEFT JOIN EMP_TIME ON t.EMP_ID_FK = EMP_TIME.EMP_ID_FK AND t.Time_ID_FK = EMP_TIME.TIME_ID_FK AND t.Day = EMP_TIME.Date_Time WHERE t.Hours <> 0 AND EMP_TIME.EMP_ID_FK IS NULL;
方法2:改用WHERE NOT EXISTS逻辑(更直观)
用NOT EXISTS替代左连接,同时加入去重,确保只插入目标表不存在且临时表无重复的记录:
INSERT INTO EMP_TIME ( EMP_ID_FK, TIME_ID_FK, Hours, Date_Time, EMP_TIME_Desc ) SELECT DISTINCT t.Emp_ID_FK, t.Time_ID_FK, t.Hours, t.Day, t.Description FROM Temp_Day_Table t WHERE t.Hours <> 0 AND NOT EXISTS ( SELECT 1 FROM EMP_TIME et WHERE et.EMP_ID_FK = t.Emp_ID_FK AND et.TIME_ID_FK = t.Time_ID_FK AND et.Date_Time = t.Day );
方法3:使用数据库内置冲突处理语句(依数据库类型而定)
- MySQL:用
ON DUPLICATE KEY UPDATE忽略冲突记录(无实际更新,仅跳过重复):
INSERT INTO EMP_TIME ( EMP_ID_FK, TIME_ID_FK, Hours, Date_Time, EMP_TIME_Desc ) SELECT t.Emp_ID_FK, t.Time_ID_FK, t.Hours, t.Day, t.Description FROM Temp_Day_Table t WHERE t.Hours <> 0 ON DUPLICATE KEY UPDATE Hours = Hours, EMP_TIME_Desc = EMP_TIME_Desc;
- SQL Server:用
MERGE语句处理插入与冲突:
MERGE INTO EMP_TIME AS target USING ( SELECT DISTINCT Emp_ID_FK, Time_ID_FK, Hours, Day, Description FROM Temp_Day_Table WHERE Hours <> 0 ) AS source ON target.EMP_ID_FK = source.Emp_ID_FK AND target.TIME_ID_FK = source.Time_ID_FK AND target.Date_Time = source.Day WHEN NOT MATCHED THEN INSERT (EMP_ID_FK, TIME_ID_FK, Hours, Date_Time, EMP_TIME_Desc) VALUES (source.Emp_ID_FK, source.Time_ID_FK, source.Hours, source.Day, source.Description);
内容的提问来源于stack exchange,提问作者A Fish
相关产品推荐
相关产品推荐

