使用新值更新表中的行,同时避开主键约束

时间:2017-04-03 17:30:46

标签: sql-server sql-update primary-key

我有两个表(让我们称之为OriginalTableNewValuesTable)有几列。我将仅讨论有关专栏。

托盘ID - OriginalTable

的主键

OriginalTable有大约35000个条目PalletID值错误。我的NewValuesTable具有正确的PalletID值。这是我的问题:

  • 我们来看一下OriginalTable
  • 的样本集

enter image description here

  • 这些值都错了。这些需要替换为NewValuesTable中的新值。像这样:

enter image description here

  • 我不知道问题是否明显,但让我解释一下。突出显示的字段是问题。当我将21更新为22时,会出现PrimaryKey Constraint相关错误,因为它是重复键。与3468相同。我该如何解决这个问题?

这就是我的想法:可能会将Duplicate Key例外的值编辑为W**。例如,22表格中的NewValue变为W2234变为W34。添加W或类似的东西。然后使用这些值更新表。然后更新OriginalTable的{​​{1}}字段以删除PalletID

这看起来像是一种明智的方式吗?有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

使用前缀更新行的一个潜在问题是,如果出现任何问题,您将留下带前缀的主键,因为将它们更新为新值会违反约束。您在填充时实际上禁用了约束,这为该群体带来了风险。

我将构建一个相同的空表(包括任何约束),前缀为某些东西,以将其标识为非生产表。然后用正确的值填充它。验证所有数据都正确后,在单个语句中更改表名称。在更新名称之前,请确保没有针对原始表的正在运行的事务。

答案 1 :(得分:1)

这里有一些SQL来演示如何一次性更新所有内容。我已经包含了一些额外的脚本,这些脚本可以让您在不破坏测试数据的情况下更好地测试测试环境中的更新SQL:

set xact_abort on -- make sure it rolls back if error
go

create table #t1 (link int primary key, id char)
create table #t2 (link int, id char)

insert into #t1 
select 1, 'a' union
select 2, 'b' union
select 3, 'c'

insert into #t2
select 2, 'c' union
select 3, 'd'

BEGIN TRAN

select * from #t1
select * from #t2

select * from #t1 a 
left join #t2 b on a.link = b.link

UPDATE #t1 
set id = b.id
from #t1 a
join #t2 b on a.link = b.link

select * from #t1

ROLLBACK
--commit

drop table #t1
drop table #t2