使用相应的非空源字段更新目标表中的任何列

时间:2012-09-04 19:06:11

标签: tsql sql-server-2005 merge

这可能是一个熟悉的问题,但我没有在搜索中找到答案。我确实有一个解决方案(如下所示),涉及每个非键列上的COALESCE,我想知道是否存在动态TSQL例程,或者可能是一种不同的方式论坛化查询,而不涉及明确命名所有列。

我有两个表,“targetTable”和“deltaTable”,它们具有相同的字段名称和类型。两者都有一个唯一的密钥,“id”。

Deltatable的数据已针对targetTable中的相应行进行了更改。值未更改的任何列都为null。我想更新targetTable中在deltaTable的相应行中具有非空值的列。 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

1 个答案:

答案 0 :(得分: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