2012-09-04 15 views
0

這可能是一個熟悉的問題,但我在搜索中找不到答案。我確實有一個涉及每個非關鍵列的COALESCE的解決方案(如下所示),我想知道是否有一個動態TSQL例程,或者是一種不涉及明確命名所有列的查詢構建方法。使用相應的非空源字段更新目標表中的任何列

我有兩個表,「targetTable」和「deltaTable」,它們具有相同的字段名稱和類型。兩者都有一個獨特的關鍵,「身份證」。

Deltatable的數據已經在targetTable中的相應行中發生了變化。值未更改的任何列爲空。我想更新deltaTable的相應行中具有非空值的targetTable中的列。 DetlaTable.id保證存在於TargetTable.id中,我從不想將字段更新爲NULL。

我正在使用SQL Server 2005(它沒有合併語句,不是我知道它會幫助)。

因此,如果targetTable行看起來像

id | name | dob  | next_appt 
    5 Bill  1-1-2012 | 3-3-2015 

和deltaTable行看起來像

id | name  | dob  | next_appt 
    5 | NULL  | NULL  | 4-4-2015 

我想targetTable更新

id | name | dob  | next_appt 
    5 Bill  1-1-2012 | 4-4-2015 

我現在,我想有哪些改進之處是:

UPDATE target 
SET target.colA = COALESCE(delta.colA, target.colA), 
    target.colN = COALESCE(delta.colN, target.colN) 
FROM delta JOIN target on delta.id = target.id 
+0

與這兩個'UPDATE'和'MERGE',你必須指定您正在更新的列。你可以建立你的字符串並用'EXEC'來執行它,但是這樣可以使你注意到SQL注入的可能性,難以維護的代碼和較慢的性能。我會說你的查詢看起來很好。 – LittleBobbyTables

+0

我同意查詢看起來很好。您可以動態構建查詢,但除非您有令人信服的理由,否則我不會考慮它。 – Narthring

+0

謝謝你,littlebobbytables和narthring,我可能會接受GilM的答案,一旦我測試出來,這是一種非常不錯的選擇。我們的部門沒有控制架構,但必須轉換成一堆表格,這些腳本在專有gui中進行轉換並複製到一批項目中,可能會使動態查詢的複雜性值得。 –

回答

0

我不知道這是一個偉大的想法,但如果你真的想這樣做,你可以做這樣的事情:

DECLARE @sql nvarchar(max) 
SET @sql = N'UPDATE target SET 
'; 
SELECT @sql = @sql + N' target.'+QUOTENAME([name]) + ' = COALESCE(delta.' + QUOTENAME([name]) + ', target.' + QUOTENAME([name]) + '), 
' 
FROM sys.columns 
where object_id = object_id('target') AND [name] != 'id' 
order by [column_id] 

SET @sql = STUFF(@sql,LEN(@sql)-2,1,''); -- strip off the last commma 
set @sql = @sql + 
'FROM delta 
JOIN target ON delta.id = target.id' 

EXECUTE sp_executesql @sql 
+0

謝謝,這讓我開始。 –

相關問題