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

Tsql 使用相应的非空源字段更新目标表中的任何列,tsql,sql-server-2005,merge,Tsql,Sql Server 2005,Merge,这可能是一个熟悉的问题,但我在搜索中没有找到答案。我确实有一个解决方案(如下所示),涉及合并每个非键列,我想知道是否有一个动态TSQL例程,或者可能有一种不同的方式来计算查询,而不涉及显式命名所有列 我有两个表,“targetTable”和“deltaTable”,它们具有相同的字段名和类型。两者都有一个唯一的键“id” Deltatable中对应行的数据已更改。值未更改的任何列都为null。我想更新targetTable中的列,这些列在deltaTable的相应行中具有非null值。Detla

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

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

Deltatable中对应行的数据已更改。值未更改的任何列都为null。我想更新targetTable中的列,这些列在deltaTable的相应行中具有非null值。DetlaTable.id保证存在于TargetTable.id中,我永远不想将字段更新为NULL

我使用的是SQLServer2005(它没有merge语句,我不知道它会有帮助)

所以如果一个目标行看起来像

  id | name    |  dob        | next_appt
  5    Bill       1-1-2012   | 3-3-2015
  id | name     | dob        | next_appt
  5  | NULL     | NULL       | 4-4-2015
一个可删除的行看起来像

  id | name    |  dob        | next_appt
  5    Bill       1-1-2012   | 3-3-2015
  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

我不确定这是一个好主意,但如果你真的想这么做,你可以这样做:

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

使用
UPDATE
MERGE
,您必须指定要更新的列。您可以构建字符串并使用
EXEC
执行它,但这会让您面临SQL注入的可能性,代码维护困难,性能低下。我认为你的问题看起来很好。我同意这个问题看起来很好。你可以动态地构建查询,但除非你有一个令人信服的理由,否则我不会考虑。谢谢,LITTLE BoBySt表和Nalthink,我可能会接受GilM的答案,一旦我测试出来,这不是一个很好的选择方案。我们部门不控制模式的一堆表,但必须转换为,在专有gui中进行转换并为一堆项目复制的脚本,可能会使动态查询的复杂性变得值得。谢谢,这让我开始了。