这可能是一个熟悉的问题,但我没有在搜索中找到答案。我确实有一个解决方案(如下所示),涉及每个非键列上的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
答案 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