获取新的SQL记录ID

获取新的SQL记录ID,sql,sql-server,sql-server-2005,asp-classic,Sql,Sql Server,Sql Server 2005,Asp Classic,如何为刚插入的新记录获取自动生成的ID? (使用ASP classic和MSSQL 2005) 使用@@IDENTITY可能会产生意外的结果,因此请小心使用该标识。将记录插入到其他表的触发器将导致@@IDENTITY值更改-其中SCOPE_IDENTITY()将仅为您提供当前作用域中的最后一个标识 下面的示例将显示@@IDENTITY和SCOPE_INSERT()之间的差异,以及它们如何返回不同的值 use tempdb go create table table1 (ID int id

如何为刚插入的新记录获取自动生成的ID? (使用ASP classic和MSSQL 2005)

使用@@IDENTITY可能会产生意外的结果,因此请小心使用该标识。将记录插入到其他表的触发器将导致@@IDENTITY值更改-其中SCOPE_IDENTITY()将仅为您提供当前作用域中的最后一个标识

下面的示例将显示@@IDENTITY和SCOPE_INSERT()之间的差异,以及它们如何返回不同的值

use tempdb
go
create table table1
    (ID int identity)
go
create table table2
    (ID int identity(100, 1))
go
create trigger temptrig 
    on table1 
    for insert
as
begin

    insert  table2 
     default values;

end
go
insert  table1 
default values;
select  SCOPE_IDENTITY(), 
        @@IDENTITY
这里没有人讨论过的另一个选项是使用SQL2005中的OUTPUT子句。在这种情况下,您只需将output子句添加到insert中,然后从代码中捕获该记录集。这在插入多条记录而不是仅插入1条记录时效果很好

use tempdb
go
create table table1
    (ID int identity)
go
insert   table1 
output   inserted.ID
default values;
--OR...
insert   table1 
output   inserted.$identity
default values;

“选择@@IDENTITY”通常有效,但可能返回由于触发器或其他原因插入的记录的标识,而不是原始记录的标识

我建议您选择SCOPE_IDENTITY。它返回仅在当前范围内插入的值


还有一个“IDENT_CURRENT(tablename)”,返回为特定表插入的最后一个标识。

SELECT@@identity或SELECT SCOPE_identity()都可以工作,但是选择SCOPE_identity()更安全,因为它返回当前范围内最后一个自动生成的标识。例如,假设我们有一个名为ScopeIDTable的表,在这个表上有一个触发器。此触发器将插入到TriggerIdTable的记录中。两个表都有一个自动递增列

如果使用SELECT@@Identity,您将获得该会话中的最后一个自动增量,它将是从触发器(TriggerIdTable)中生成的Id


如果使用SELECT SCOPE_IDENTITY(),您将从ScopeId表中获取id。

有三种方法可以获取sql中的最后一个标识。

其他人已经提到了它们,但为了完整性:

  • @@标识-还可以返回在同一范围内的其他对象中创建的标识(思考触发器)
  • IDENT_CURRENT-仅限于一个表,但不限于您的作用域,因此它可能会对繁忙的表产生不好的结果
  • Scope_Idenity()-仅限于请求的范围。99%的时间都在使用它
此外,有三种方法可以获取该ID并将其返回到您的客户端代码:

  • 在存储过程中使用输出参数

    INSERT INTO [MyTable] ([col1],[col2],[col3]) VALUES (1,2,3); 
    SELECT @OutputParameterName = Scope_Identity();
    
  • 使用返回值

    INSERT INTO [MyTable] ([col1],[col2],[col3]) VALUES (1,2,3); 
    Return Scope_Identity();
    
  • 将id选择到结果集中。例如,您的sql语句如下所示:

    Dim ResultID As Integer
    Dim strSQL As String
    strSQL = "INSERT INTO [MyTable] ([col1],[col2],[col3]) VALUES (1,2,3); SELECT Scope_Identity();"
    rsResults.Open strSQL, oConn
    ResultID = rsResults("ID")
    
不幸的是(或幸运的是,从我的角度来看),我的经典ASP太远了,无法从客户机代码中显示前两个示例。

您运行查询

select scope_identity()
使用相同的数据库连接,然后再对其执行任何其他操作。结果是,正如您可能期望的那样,一个记录集包含一行,而该行只有一个字段。您可以使用索引0访问该字段,如果愿意,也可以为其命名:

select scope_identity() as lastId

如果需要以基于集合的方式同时插入多个记录,则会变得更有趣

我有时使用GUIDs生成clientside(但对于经典的ASP,您可能需要使用实用程序来生成值),或者更常见的是,在服务器端的GUID键列上使用NEWSQUENTIALID()约束

但我知道不是每个人都喜欢GIUDS,原因很有道理(它们的大小以及它如何影响索引/分页)


我一直想知道为什么会有人想使用

@@identity

select scope_identity() 

显然,这是实现Scot要求的最省钱的方法。

感谢所有建议选择SCOPE_IDENTITY()的人。我能够创建一个存储过程:

USE [dbname]
GO 
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[spInsert]
(
   @Nn varchar(30)
)
AS
BEGIN TRANSACTION InsertRecord 
   INSERT INTO A (Nn) 
   VALUES (@Nn) 
   SELECT NewID = SCOPE_IDENTITY()   -- returns the new record ID of this transaction
   COMMIT TRANSACTION InsertRecord
并使用VB调用存储过程:

Dim strNn '<- var to be passed'
Set cn = Server.CreateObject("ADODB.Connection") 
connectString = "DSN" 
cn.Open connectString, "user", "PW0rd" 
Set rs = Server.CreateObject("ADODB.Recordset") 
set rs = cn.Execute("EXEC [dbname].[dbo].[A] @Nn=" & strNn)
'return the value'
resultID = rs(0)

Dim strNn'感谢所有建议选择范围\标识()的人。我能够创建一个存储过程:SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER procedure[dbo]。[spIns](@N varchar(30)AS BEGIN TRANSACTION Ins INSERT in a(N)VALUES(@N)SELECT NewID=SCOPE_IDENTITY())使用VB调用sp:
SET cn=Server.CreateObject(“ADODB.Connection”)connectString=“DSN”cn.Open connectString,“user”,“PW0rd”Set rs=Server.CreateObject(“ADODB.Recordset”)Set rs=cn.Execute(“EXEC[DB].[dbo].[A]@Str=“&Str”)返回值:
resultID=rs(0)
Dim strNn '<- var to be passed'
Set cn = Server.CreateObject("ADODB.Connection") 
connectString = "DSN" 
cn.Open connectString, "user", "PW0rd" 
Set rs = Server.CreateObject("ADODB.Recordset") 
set rs = cn.Execute("EXEC [dbname].[dbo].[A] @Nn=" & strNn)
'return the value'
resultID = rs(0)