将OUTPUT更新为变量

Cor*_*son 55 sql-server

我正在尝试执行更新和选择......基本上,基于索引进行更新,然后选择已更新的行ID.

使用OUTPUT子句很简单:

UPDATE Foo
SET Bar = 1
OUTPUT INSERTED.Id
WHERE Baz = 2
Run Code Online (Sandbox Code Playgroud)

但现在,我如何将其变为变量?

DECLARE @id INT
Run Code Online (Sandbox Code Playgroud)

这三个不起作用:

UPDATE Foo
SET Bar = 1
OUTPUT @id = INSERTED.Id
WHERE Baz = 2

SET @id =
(UPDATE Foo
 SET Bar = 1
 OUTPUT INSERTED.Id
 WHERE Baz = 2)

SET @id =
(SELECT Id FROM (UPDATE Foo
                 SET Bar = 1
                 OUTPUT INSERTED.Id Id
                 WHERE Baz = 2) z)
Run Code Online (Sandbox Code Playgroud)

最后一个包括在内,因为当管理工作室中的所有红色波浪线消失时,它让我暂时兴奋.唉,我收到这个错误:

A nested INSERT, UPDATE, DELETE, or MERGE statement is not allowed in a SELECT statement that is not the immediate source of rows for an INSERT statement.
Run Code Online (Sandbox Code Playgroud)

And*_*mar 85

由于更新可能会影响多行,因此需要使用表来存储其结果:

declare @ids table (id int);

UPDATE Foo
SET Bar = 1
OUTPUT INSERTED.Id INTO @ids
WHERE Baz = 2
Run Code Online (Sandbox Code Playgroud)

如果您确定只有一行会受到影响,您可以将ID拉出:

declare @id int
select  top 1 @id = id
from    @ids
Run Code Online (Sandbox Code Playgroud)


Arp*_*ain 69

如果只有一行受到影响,则可以在没有表变量的情况下完成.

DECLARE @id INT

UPDATE Foo 
SET Bar = 1, @id = id 
WHERE Baz = 2

SELECT @id 
Run Code Online (Sandbox Code Playgroud)

  • 我从来没有想过这个.非常好! (3认同)
  • 谢谢 Cory,我想知道更新中的 set 关键字是否能够设置变量并且它起作用了! (2认同)
  • 这种方法有一些限制;例如,如果您有 rowversion 列,则这将返回*最后* rowversion,而不是更新后的结果。 (2认同)

小智 8

或者,如果只有一行受到影响:

DECLARE @id INT

UPDATE Foo 
SET @id = Bar = 1  ---Yes, this is valid!
WHERE Baz = 2

SELECT @id 
Run Code Online (Sandbox Code Playgroud)