【问题标题】:UPDATE OUTPUT into a variable将输出更新到变量中
【发布时间】:2013-05-30 23:07:16
【问题描述】:

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

使用 OUTPUT 子句很简单:

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

但是现在,我如何把它变成一个变量呢?

DECLARE @id INT

这三个不起作用:

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)

最后一个包括在内,因为当 Management Studio 中所有红色波浪线消失时,它让我暂时感到兴奋。唉,我得到这个错误:

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.

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    如果只有一行受到影响,可以不用表变量来完成。

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

    【讨论】:

    • 我从来没有想过这个。非常好!
    • 谢谢 Cory,我想知道更新中的 set 关键字是否能够设置变量并且有效!
    • 这对insert 是否适用于单个受影响的行?
    • 没有@rahoolm,只有SETSELECT关键字可以修改变量,这些关键字不能与INSERT语句一起使用
    • 这种方法有一些限制;例如,如果您有一个 rowversion 列,这将返回 last rowversion,而不是您的更新产生的那个。
    【解决方案2】:

    因为一个更新会影响多行,所以它需要一个表来存储它的结果:

    declare @ids table (id int);
    
    UPDATE Foo
    SET Bar = 1
    OUTPUT INSERTED.Id INTO @ids
    WHERE Baz = 2
    

    如果你确定只有一行会受到影响,你可以像这样拉出 id:

    declare @id int
    select  top 1 @id = id
    from    @ids
    

    【讨论】:

    • 您不必为结果提供表格。您可以这样做:OUTPUT INSERTED。* 当然,这会带回所有列。
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2018-01-27
      • 2023-02-13
      相关资源
      最近更新 更多