SQL基于case语句的部分更新?

时间:2016-10-29 09:01:53

标签: sql sql-server database sql-server-2012 sql-server-2014

最近我不得不对表进行一些变量更新,虽然我知道MERGE语句(虽然需要赶上所有这些!),但我还执行了以下语句来自动更新表并希望检查这是否是一个好主意"或者有一些我不知道的隐藏后果。

所以在我的情况下,我将一个主键传递给一个表,但是根据传递的参数是否为null,我更新了列..显然,如果你必须确保强制更新(状态等)然后你只需更新列..这是为了节省多个" IF / THEN"类型结构..

create procedure sp_myprocedure
as
   @id                     bigint,
   @field1                 int = null,
   @field2                 varchar(255) = null,
   @field3                 char(1) = null
begin 

   update my_table
   set 
      field1 = case when @field1 is not null then @field1 else field1 end,
      field2 = case when @field2 is not null then @field2 else field2 end,
      field3 = case when @field3 is not null then @field3 else field3 end,
   where
      id = @id

end

在对上述情况进行一些考虑之后,或者最好是针对上述情况采用MERGE声明吗?

非常感谢,

3 个答案:

答案 0 :(得分:2)

        create procedure sp_myprocedure

        @id                     bigint,
        @field1                 int = null,
        @field2                 varchar(255) = null,
        @field3                 char(1) = null
        as
        begin 
        IF coalesce(@field1,@field2,@field3) is not null
           update dbo.my_table
           set 
           field1 = coalesce (@field1,field1),
           field2 = coalesce (@field2,field2),
           field3 = coalesce (@field3,field3)
           where id = @id
        END

答案 1 :(得分:1)

这很好,虽然它可以用更干净的方式编写。

   update my_table
   set 
      field1 = coalesce (@field1,field1)
     ,field2 = coalesce (@field2,field2)
     ,field3 = coalesce (@field3,field3)
   where
      id = @id and coalesce(@field1,@field2,@field3) is not null

您也可以将coalesce(@field1,@field2,@field3) is not null移动到包装块

if coalesce(@field1,@field2,@field3) is not null
begin

   update my_table
   set 
      field1 = coalesce (@field1,field1)
     ,field2 = coalesce (@field2,field2)
     ,field3 = coalesce (@field3,field3)
   where
      id = @id

end

MERGE 声明与此无关 使用 MERGE ,决定是否 INSERT 更新删除基于不存在/存在的记录库源/目标表中具有相同合并键的记录 在您的情况下,它总是更新

答案 2 :(得分:1)

回答@Dudu Markovitz的回答:

  

MERGE声明与此无关。

我不同意,我认为MERGE在这里完全相关。

我们的想法是使用参数值创建源表表达式,以更新目标表:

MERGE my_table T
   USING ( VALUES ( @id, @field1, @field2, @field3 ) ) 
      AS S ( id, field1, field2, field3 )
      ON T.id = S.id
WHEN MATCHED THEN
   UPDATE
      SET field1 = COALESCE( S.field1, T.field1 ),
          field2 = COALESCE( S.field2, T.field2 ),
          field3 = COALESCE( S.field3, T.field3 );

当然,如果只有一个表值参数(应该有争议)那么MERGE的相关性就更明显了。