【问题标题】:get new SQL record ID获取新的 SQL 记录 ID
【发布时间】:2013-05-21 20:56:25
【问题描述】:

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

【问题讨论】:

  • 感谢所有建议 SELECT SCOPE_IDENTITY() 的人。我能够创建一个存储过程: SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[spIns] (@N varchar(30) AS BEGIN TRANSACTION Ins INSERT INTO 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)
    '返回值:
    结果ID = rs(0)

标签: sql sql-server sql-server-2005 asp-classic


【解决方案1】:
SELECT SCOPE_IDENTITY() 

使用@@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

这里没有人讨论的另一个选项是使用 SQL 2005 中的 OUTPUT 子句。在这种情况下,您只需将输出子句添加到插入中,然后从代码中捕获该记录集。这在插入多条记录而不是仅插入 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;

【讨论】:

    【解决方案2】:

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

    SELECT SCOPE_IDENTITY 是我推荐的。它返回仅在当前范围内插入的值。

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

    【讨论】:

      【解决方案3】:

      获取最后一个身份的三种方式在sql中

      他们已经被其他人提到过,但为了完整起见:

      • @@IDENTITY - 还可以返回在同一范围内的其他对象中创建的 ID(想想触发器)
      • 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")
        

      不幸的是(或者幸运的是,从我的角度来看)我的 Classic ASP 太过分了,无法从客户端代码中展示前两个示例。

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          【解决方案5】:

          您运行查询

          select scope_identity()
          

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

          select scope_identity() as lastId
          

          【讨论】:

            【解决方案6】:

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

            @@identity
            

            因为

            select scope_identity() 
            

            显然是完成 Scot 要求的最省钱的方法。

            【讨论】:

              【解决方案7】:

              如果需要以基于集合的方式一次插入多条记录,它会变得更有趣。

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

              我知道不是每个人都喜欢 GIUDS,但出于一些非常正当的原因(它们的大小以及它如何影响索引/分页)。

              http://www.sqlmag.com/Articles/Index.cfm?ArticleID=50164&pg=2

              【讨论】:

                【解决方案8】:

                感谢所有建议 SELECT 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)
                

                我现在可以在任何时候引用新创建的 ID 时使用 resultID。

                【讨论】:

                  猜你喜欢
                  • 2021-01-10
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-12-17
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-08-23
                  • 2021-11-24
                  相关资源
                  最近更新 更多