获取最后插入的行ID(带有SQL语句)

Sna*_*yes 101 sql sql-server

我想在表中插入新记录时获取新创建的ID.

我读到这个:http://msdn.microsoft.com/en-us/library/ms177564.aspx但它需要创建临时表.

我想在执行INSERT语句后返回ID(假设只执行一次INSERT).

例:

1     Joe      Joe
2     Michael  Mike
3     Zoe      Zoe
Run Code Online (Sandbox Code Playgroud)

执行INSERT语句时,我想返回创建的ID,表示4.

可以告诉我如何使用SQL语句或不可能吗?

mar*_*c_s 194

如果您的SQL Server表具有类型INT IDENTITY(或BIGINT IDENTITY)的列,则可以使用以下命令获取最新插入的值:

INSERT INTO dbo.YourTable(columns....)
   VALUES(..........)

SELECT SCOPE_IDENTITY()
Run Code Online (Sandbox Code Playgroud)

只要您没有插入另一行,它就会起作用 - 它只返回IDENTITY此范围中分配的最后一个值.

Pinal Dave在这篇精彩的博客文章中,至少还有两个选项 - @@IDENTITY并且IDENT_CURRENT- 阅读更多关于它们如何工作以及它们以何种方式不同(并且可能会给你意想不到的结果).

  • 请注意,`SCOPE_IDENTITY()`也可能产生不正确的结果(在并行性下),请参阅http://support.microsoft.com/kb/2019779 - 该修复程序于上周首次针对2008 R2 SP1 CU5提供.在所有早期版本中,解决方法是将maxdop设置为1,保留一个不使用并行性的固定计划(我没有测试过这个),或使用输出子句. (9认同)
  • @youcantryreachingme:好吧,你的表“Client”**没有**任何“IDENTITY”列 - 所以“INSERT INTO Client()...”显然不会***触发任何正在生成的身份,所以 `SCOPE_IDENTITY()` 将理所当然地为 NULL :.... (2认同)
  • @marc_s 感谢您如此有力的解释!哇!我没想到这么强调!我认为主键(唯一的*标识符*)可能与表的*identity* 列相同(尽管我确实想知道非“int”和复合主键),这是我的疏忽。对于其他遇到此问题的人,这里有一个很好的解释:/sf/ask/300539851/ Between-a-primary-key-and-identity (2认同)

Aar*_*and 53

假设一个简单的表:

CREATE TABLE dbo.foo(ID INT IDENTITY(1,1), name SYSNAME);
Run Code Online (Sandbox Code Playgroud)

我们可以捕获IDENTITY表变量中的值以供进一步使用.

DECLARE @IDs TABLE(ID INT);

-- minor change to INSERT statement; add an OUTPUT clause:
INSERT dbo.foo(name) 
  OUTPUT inserted.ID INTO @IDs(ID)
SELECT N'Fred'
UNION ALL
SELECT N'Bob';

SELECT ID FROM @IDs;
Run Code Online (Sandbox Code Playgroud)

这个方法的好处是(a)它处理多行插入(SCOPE_IDENTITY()只返回最后一个值)和(b)它避免了这种并行性错误,这可能导致错误的结果,但到目前为止只在SQL Server 2008中修复R2 SP1 CU5.

  • 只有通过创建模糊的错误才能将编程视为工作安全以外的其他东西,这才是正确的</ sarcasm> (3认同)

Max*_*ion 40

您可以使用:

SELECT IDENT_CURRENT(‘tablename’)
Run Code Online (Sandbox Code Playgroud)

访问特定表的最新标识.

例如,考虑以下代码:

INSERT INTO dbo.MyTable(columns....) VALUES(..........)

INSERT INTO dbo.YourTable(columns....) VALUES(..........)

SELECT IDENT_CURRENT(‘MyTable’)

SELECT IDENT_CURRENT(‘YourTable’)
Run Code Online (Sandbox Code Playgroud)

这将产生相应表的正确值.

它返回IDENTITY表中生成的最后一个值,无论创建该值的连接如何,也不管生成该值的语句的范围如何.

IDENT_CURRENT不受范围和会话的限制; 它仅限于指定的表格.IDENT_CURRENT返回在任何会话和任何范围内为特定表生成的标识值.

  • 根据你的陈述:"不管创建值的连接是什么" - 这听起来没用 - 如果另一个连接在我的后面插入一行,我会得到他的号码 - 我稍后会用它来尝试更新我插入的行,但相反,会更新他的.对? (7认同)
  • 我无法理解这是如何获得 49 票赞成的。“IDENT_CURRENT”对于确定插入的最后一行“*I*”是完全不可靠的,但它是_也许_获取我_或其他人_插入的最后一行的好方法。请参阅[最后一次,不,你不能信任 IDENT_CURRENT()](https://sqlperformance.com/2014/01/t-sql-queries/ident-current) (2认同)