使用OUTPUT子句

时间:2016-06-20 14:25:16

标签: sql sql-server-2012 sql-update

我有一个dbo.ChangeLog表,我们将更改插入到某些列中。 我这样做的正常方式是:

UPDATE dbo.Table
SET FirstName = NewFirstName
OUTPUT
Deleted.Id
'FirstName' as Type
Deleted.FirstName as OldValue
Inserted.FirstName as NewValue
INTO dbo.ChangeLog
FROM dbo.Table as t
INNER JOIN dbo.Table2 as t2 on t.Id = t2.Id

当我需要更新FirstName AND LastName时,我通常会做2个更新语句,但我想知道是否可以在同一个更新语句中更新多个列,同时还插入对dbo.ChangeLog表的更改。

1 个答案:

答案 0 :(得分:0)

如果你可以改变dbo.ChangeLog的定义,它变得微不足道,但我认为这不是你想要的。

我使用表变量来处理这个问题并使用CROSS APPLY“取消”数据(但是使用UNPIVOT也可以正常工作......):

SELECT 1 as id, 'Dan                        ' as FirstName, 'Field                               ' as LastName INTO #tbl

DECLARE @changes TABLE (id int, old1 varchar(250), new1 varchar(250), old2 varchar(250), new2 varchar(250))

UPDATE  #tbl
SET FirstName = 'asdf', LastName = NEWID()
OUTPUT deleted.id
        ,deleted.FirstName, inserted.FirstName
        ,deleted.LastName, inserted.LastName 
    INTO @changes(id, old1, new1, old2, new2)

-- change this to an INSERT dbo.ChangeLog
SELECT unp.*
FROM @changes
CROSS APPLY (VALUES (id, old1, new1)
                    ,(id, old2, new2)) unp(id, oldval, newval)


DROP TABLE #tbl

只需将最后一个SELECT更改为INSERT即可。请注意,这需要一个中间表变量或临时表,因为您无法在CROSS APPLY子句中使用UNPIVOTOUTPUT