使用OUTPUT Clause sql仅获取更新的列

时间:2016-12-14 16:11:54

标签: sql sql-server

我有以下程序来跟踪表中的列更改。

ALTER PROCEDURE [UpdateAddress]
@id bigint=0,
@fullname varchar(200)='',
@address varchar(200)='',
@city varchar(200)='',
@state varchar(200)=''
AS
declare @desc varchar(500);
BEGIN
DECLARE @MyTableVar table(  
   fullname varchar(200) NULL,  
   address varchar(200) NULL , 
  city varchar(200) NULL ,
 state varchar(200) NULL );


        BEGIN
            UPDATE [Address]
            SET 
                fullname=@fullname,
                address=@address,
                city=@city,
                state=@state

             OUTPUT deleted.fullname,  
      deleted.address,  
      deleted.city,  
      deleted.state
INTO @MyTableVar
             WHERE [Id]=@id

这里我将获得所有更新但未更新的列。所以我们需要比较deleted.fullname and inserted.fullname这两个。所以,如果我在一个表中有20列,并且只更新了2列。没有比较,有没有办法只使用输出子句获取更新列?

示例:我有20列。因为我只更新了全名和地址。所以我应该得到Fullname,地址已更改。没有任何比较。是否有任何sql内置函数,如updated_column()

谢谢...

1 个答案:

答案 0 :(得分:0)

您可以在output中使用标量表达式。因此,您可以表示“无变化”,例如NULL

OUTPUT (case when inserted.fullname <> deleted.fullname then deleted.fullname end),  
       (case when inserted.address <> deleted.address then deleted.address end),
       (case when inserted.city <> deleted.city then deleted.city end),  
       (case when inserted.state <> deleted.state then deleted.state end)

如果之前的列值永远不是NULL,那么这是明确的。

您也可以使用相同的想法将已更改的列列在一起:

OUTPUT deleted.fullname,  
       deleted.address,  
       deleted.city,  
       deleted.state,
       ((case when inserted.fullname <> deleted.fullname then 'fullname;' else '' end) + 
        (case when inserted.address <> deleted.address then 'address;' else '' end) + 
        (case when inserted.city <> deleted.city then 'city;' else '' end) +   
        (case when inserted.state <> deleted.state then 'state;' else '' end)
       )

包含NULL检查的表达式会有点复杂。