批量复制同表数据修改指定字段,遇标识列与主键约束问题求助
解决批量复制ProductLocation表数据并修改指定字段的问题
问题根源
你碰到的两个错误都是因为主键(标识列)处理错误:
- 第一个错误:用
select *插入时会把自动递增的主键列也带进去,哪怕开了IDENTITY_INSERT,也必须明确列列表,而且强行插入原主键值必然会重复。 - 第二个错误:指定列的时候把主键列也包含进去了,导致插入了已存在的主键值,触发约束冲突。
最简解决方案
不用临时表就能高效完成,核心是排除主键列,只插入需要的其他字段:
假设你的ProductLocation表主键是ProductLocationID(自动生成的标识列),执行下面的SQL:
INSERT INTO ProductLocation ( BillingLocationID, DepartmentID, -- 这里替换成表中除ProductLocationID外的所有列 -- 例如:ProductID, LocationDesc, CreatedDate... ) SELECT 3 AS BillingLocationID, -- 把原BillingLocationID=1替换为3 DepartmentID, -- 对应上面的列列表,保持字段顺序一致 -- ProductID, LocationDesc, CreatedDate... FROM ProductLocation WHERE BillingLocationID = 1 AND DepartmentID = 3
若需用临时表中转
如果一定要用临时表,得确保临时表不包含主键列:
-- 创建不含主键的临时表 SELECT BillingLocationID, DepartmentID, -- 只选除主键外的其他列 ProductID, LocationDesc, CreatedDate... INTO #temptablepop FROM ProductLocation WHERE BillingLocationID = 1 AND DepartmentID = 3 -- 修改目标字段 UPDATE #temptablepop SET BillingLocationID = 3 -- 插入时指定列(排除主键) INSERT INTO ProductLocation ( BillingLocationID, DepartmentID, ProductID, LocationDesc, CreatedDate... ) SELECT * FROM #temptablepop -- 清理临时表 DROP TABLE #temptablepop
重要提示
- 批量新增行时,永远不要手动插入原主键值,数据库会自动为新行生成唯一的主键。
IDENTITY_INSERT只有在需要手动指定标识列值时才用(比如数据恢复),这个场景完全不需要开启。
内容的提问来源于stack exchange,提问作者Chrishan Kankanamge
相关产品推荐
相关产品推荐

