SQL Server - INSERT后的返回值

时间:2011-10-27 14:46:41

标签: sql sql-server sql-server-2008

我试图在INSERT语句之后得到一个键值。 例: 我有一个包含属性name和id的表。 id是生成的值。

    INSERT INTO table (name) VALUES('bob');

现在我想在同一步骤中恢复身份。这是怎么做到的?

我们正在使用Microsoft SQL Server 2008。

15 个答案:

答案 0 :(得分:409)

无需单独的SELECT ...

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

这也适用于非IDENTITY列(例如GUID)

答案 1 :(得分:161)

使用SCOPE_IDENTITY()获取新的ID值

INSERT INTO table (name) VALUES('bob');

SELECT SCOPE_IDENTITY()

http://msdn.microsoft.com/en-us/library/ms190315.aspx

答案 2 :(得分:37)

INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

是最安全的赌注,因为在带触发器的表上存在OUTPUT子句冲突的已知问题。这使得这非常不可靠,即使您的表当前没有任何触发器 - 有人在线下添加一个会破坏您的应用程序。时间炸弹的行为。

有关更深入的解释,请参阅msdn文章:

http://blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx

答案 3 :(得分:23)

实体框架执行类似于gbn的答案:

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');

SELECT t.[CustomerID]
FROM @generated_keys AS g 
   JOIN dbo.Customers AS t 
   ON g.Id = t.CustomerID
WHERE @@ROWCOUNT > 0

输出结果存储在临时表变量中,然后选择回客户端。必须要知道问题:

  

插入可以生成多行,因此变量可以包含多行,因此可以返回多个ID

我不知道为什么EF会将短暂的表连接回真实表(在什么情况下两者不匹配)。

但那是EF的作用。

仅限SQL Server 2008或更新版本。如果是2005年那么你就不幸了。

答案 4 :(得分:10)

@@ IDENTITY是一个返回最后插入的标识值的系统函数。

答案 5 :(得分:4)

您可以使用scope_identity选择刚刚插入变量的行的ID,然后从该表中选择您想要的任何列,其中id =您从scope_identity获得的身份

请在此处查看MSDN信息http://msdn.microsoft.com/en-us/library/ms190315.aspx

答案 6 :(得分:3)

最好,最确定的解决方案是使用SCOPE_IDENTITY。 只是您必须在每次插入后获取作用域标识并将其保存在变量中,因为您可以在同一作用域中调用两个insert。 @identity和@@ identity可能起作用,但它们不是安全范围。您可能在大型应用程序中遇到问题

  declare @duplicataId int
  select @duplicataId =   (SELECT SCOPE_IDENTITY())

更多详细信息在这里Microsoft docs

答案 7 :(得分:1)

插入后有多种退出方式

  

将数据插入表中时,可以使用OUTPUT子句来   返回已插入表中的数据的副本。的   OUTPUT子句采用两种基本形式:OUTPUT和OUTPUT INTO。使用   如果要将数据返回到调用应用程序,请使用OUTPUT表格。   如果要将数据返回到表中,请使用OUTPUT INTO表单。   表变量。

DECLARE @MyTableVar TABLE (id INT,NAME NVARCHAR(50));

INSERT INTO tableName
(
  NAME,....
)OUTPUT INSERTED.id,INSERTED.Name INTO @MyTableVar
VALUES
(
   'test',...
)

IDENT_CURRENT :它返回在任何会话中为特定表或视图创建的最后一个身份。

SELECT IDENT_CURRENT('tableName') AS [IDENT_CURRENT]

SCOPE_IDENTITY :它返回来自同一会话和相同范围的最后一个身份。范围是存储过程/触发器等。

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];  

@@ IDENTITY :它返回同一会话中的最后一个身份。

SELECT @@IDENTITY AS [@@IDENTITY];

答案 8 :(得分:1)

有多种方法可以在插入命令后获取最后插入的ID。

  1. @@IDENTITY:无论当前表和生成该值的语句范围如何,它都会返回当前会话中在Connection上生成的最后一个Identity值
  2. SCOPE_IDENTITY():它返回在当前连接的当前作用域中,由insert语句生成的最后一个标识值,与表无关。
  3. IDENT_CURRENT(‘TABLENAME’):无论指定任何连接,会话或作用域,它都会返回在指定表上生成的最后一个标识值。 IDENT_CURRENT不受范围和会话的限制;它仅限于指定的表。

现在,要确定哪一个与我的需求完全匹配似乎更加困难。

我最喜欢SCOPE_IDENTITY()。

如果在insert语句中将select SCOPE_IDENTITY()与TableName一起使用,则将按照您的期望获得准确的结果。

来源:CodoBee

答案 9 :(得分:1)

推荐使用SCOPE_IDENTITY()来获取新的ID值,但不要使用“OUTPUT Inserted.ID”

如果insert语句抛出异常,我除了直接抛出。但是“OUTPUT Inserted.ID”将返回0,这可能不是预期的。

答案 10 :(得分:0)

当我在SQL Server中插入使用ID作为标识列的表时,这就是我使用OUTPUT INSERTED的方式:

'myConn is the ADO connection, RS a recordset and ID an integer
Set RS=myConn.Execute("INSERT INTO M2_VOTELIST(PRODUCER_ID,TITLE,TIMEU) OUTPUT INSERTED.ID VALUES ('Gator','Test',GETDATE())")
ID=RS(0)

答案 11 :(得分:0)

您可以在insert语句中附加select语句。 整数myInt = 插入table1(FName)值('Fred');选择Scope_Identity(); 这将在执行scaler时返回标识值。

答案 12 :(得分:-2)

*连接字符串中的参数顺序有时很重要。 * Provider参数的位置可以在添加行后中断记录集游标。我们在SQLOLEDB提供程序中看到了这种行为。

添加行后,行字段不可用,除非在连接字符串中将Provider指定为第一个参数。当提供程序位于连接字符串中的任何位置时(第一个参数除外),新插入的行字段不可用。当我们将Provider移动到第一个参数时,行字段神奇地出现了。

答案 13 :(得分:-3)

这可能有点老套了,但是有很多人在使用较旧的PHP,Pre 5.5或更精确。更多详细信息,请访问http://php.net/manual/en/function.mysql-insert-id.php

$last = mysql_insert_id();

答案 14 :(得分:-5)

在插入带有标识列的表后,您可以引用@@ IDENTITY来获取值: http://msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx