SQL Server输出子句变为标量变量

Ben*_*ttr 122 t-sql sql-server

有没有"简单"的方法来做到这一点,或者我需要传递一个带有"OUTPUT ... INTO"语法的表变量?

DECLARE @someInt int

INSERT INTO MyTable2(AIntColumn)
OUTPUT @SomeInt = Inserted.AIntColumn
VALUES(12)
Run Code Online (Sandbox Code Playgroud)

Mik*_*son 148

你需要一个表变量,它可以很简单.

declare @ID table (ID int)

insert into MyTable2(ID)
output inserted.ID into @ID
values (1)
Run Code Online (Sandbox Code Playgroud)

  • 但后来我必须"选择@someInt = ID FROM @ID".我想知道是否可以跳过那个额外的步骤(和中间表变量),如果我需要的只是结果int. (33认同)
  • 在自动生成的值的情况下,并不总是可以提前知道值(标识,计算列).我知道有很多解决方法.不过,你给了我正在寻找的答案.谢谢 (3认同)
  • 需要在常规变量中使用它吗?`DECLARE @InsertedIDResults TABLE (ID int); INSERT INTO MyTable (姓名, 年龄) OUTPUT INSERTED.ID INTO @InsertedIDResults VALUES('我的名字', 30); DECLARE @InsertedID int = (从@InsertedIDResults中选择前1个ID);` (3认同)

Ale*_* B. 28

一年之后......如果您需要的是获取表格的自动生成ID,您可以

SELECT @ReportOptionId = SCOPE_IDENTITY()
Run Code Online (Sandbox Code Playgroud)

否则,您似乎无法使用表格.

  • 显然,这在多处理器并行计划中存在问题,而OUTPUT是唯一始终值得信赖的方法. (23认同)
  • 我正在寻找的变量确实是标识列的其他内容.不过,谢谢你的回答. (6认同)
  • SCOPE_IDENTITY()可能会返回一些内容,即使*last*INSERT没有插入任何内容,对吧?这会使它在某些情况下无法使用. (6认同)
  • 最好使用输出子句 (3认同)
  • @andrewb 提到的错误已在 [2008 R2 SP1] 中修复(https://support.microsoft.com/en-us/help/2019779/you-may-receive-in Correct-values-when-using-scope-identity -和-身份)。 (2认同)

小智 10

回答

您可以用来@@IDENTITY获取最后插入的 id。

DECLARE @someInt int
INSERT INTO MyTable2(AIntColumn)
VALUES(12)
SET @someInt = @@IDENTITY;
Run Code Online (Sandbox Code Playgroud)

假设您的表有一个主键,您希望将其设置为所述变量。

示例架构

CREATE TABLE MyTable2(
    [ID] [INT] IDENTITY(1,1),
    [aIntColumn] [INT]
)
CREATE TABLE MyTable3(
    [ID] [INT] IDENTITY(1,1),
    [newInt] [INT],
    [FK_int] [INT]
)
Run Code Online (Sandbox Code Playgroud)

然后您可以在脚本的下一部分中使用它,例如

DECLARE @someInt INT;
INSERT INTO MyTable2(AIntColumn)
VALUES(12)
SET @someInt = @@IDENTITY;

--do something else
DECLARE @someInt2 INT;
INSERT INTO MyTable3(newInt, FK_int)
VALUES(101, @someInt)
SET @someInt2 = @@IDENTITY;

SELECT @someInt AS 'First Inserted ID ',  @someInt2 AS 'Second inserted ID';
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是@@IDENTITY 不值得信任。有时您会从不同的表中获取最后插入的 id。在生产中诊断这样的错误非常困难。使用 OUTPUT 子句代替 (2认同)
  • 我不反对,这没有错,但我只是想说有更新、更安全的方法来获取身份。 (2认同)

Jay*_*y13 9

稍后但仍然值得一提的是,您还可以使用变量在 UPDATE 的 SET 子句或 SELECT 的字段中输出值;

DECLARE @val1 int;
DECLARE @val2 int;
UPDATE [dbo].[PortalCounters_TEST]
SET @val1 = NextNum, @val2 = NextNum = NextNum + 1
WHERE [Condition] = 'unique value'
SELECT @val1, @val2
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,@val1 具有前值,@val2 具有后值,尽管我怀疑触发器的任何更改都不会在 val2 中,因此在这种情况下您必须使用输出表。除了最简单的情况外,我认为输出表在您的代码中也将更具可读性。

一个非常有用的地方是,如果您想将一列转换为逗号分隔的列表;

DECLARE @list varchar(max) = '';
DECLARE @comma varchar(2) = '';
SELECT @list = @list + @comma + County, @comma = ', ' FROM County
print @list
Run Code Online (Sandbox Code Playgroud)

  • 与所要求的完全不同,根本没有帮助,因为我正在寻找一种使用“INSERT-OUTPUT-VALUES”方法将“OUTPUT”值分配给“INSERT”子句中的变量的方法正如提问者所问。 (2认同)