2017-04-03 39 views
0

我有兩個表(我們稱它們爲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**。例如,NewValue表中的22表變爲W22,34變成W34。添加一個W或類似的東西。然後用這些值更新表格。然後更新OriginalTablePalletID字段以刪除W

這似乎是一個聰明的方式去做這件事嗎?有一個更好的方法嗎?

+0

您是否一次更新一行?兩個表的行數是否相同?即使一張桌子需要更新,它們是否都正確訂購? – TDP

+0

我使用'update'和'join'更新近35,000行。他們點了,是的。但是'PalletID'字段的值不像問題中那麼簡單。一個典型的'PalletID'看起來像'H2333431'。 「NewValues」表有35,000行,因爲那些是需要改變的。 'OriginalTable'有超過100,000行,但只有35,000行錯誤的'PalletID'存在問題。 –

+1

如果您一次更新所有行,則不應該有任何問題。 –

回答

1

用前綴更新行的潛在問題是,如果出現任何問題,您將留下前綴主鍵,因爲將它們更新爲新值會違反約束條件。從本質上來說,在填充該限制時會禁用該限制,從而爲該羣體帶來風險。

我會建立一個相同的空表(包括任何約束),前面加上一些東西來標識它爲非生產表。然後用正確的值填充它。一旦您確認所有數據都正確,請在單個語句中更改表名。在更新名稱之前,只要確保沒有針對原始表的正在運行的事務。

+0

我真的接近做前綴方法,你實際上已經保存了我曾經這樣做過,並且一直在努力,我完全忘了,這是一個好主意,我會看看其他人是否有任何用處,如果沒有,可能會繼續與你的一樣,謝謝。 –

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