【问题标题】:IDENT_CURRENT returns the last identity value but SCOPE_IDENTITY does notIDENT_CURRENT 返回最后一个标识值,但 SCOPE_IDENTITY 不返回
【发布时间】:2012-02-21 20:37:22
【问题描述】:

我有一个 SQL Server 作为 asp.net 应用程序的后端。多个人可能会“同时...”在同一个表中插入数据。

当我从这篇文章中阅读解决方案/答案时:scope_identity vs ident_current

那么我不应该使用Ident_current,因为我可以获得另一个用户的插入ID。

但是使用Select Scope_Identity(); 会返回NULL,而Select IDENT_CURRENT('tableName') 会返回我使用SQL Server Management Studio 检查的正确ID。

我在SqlTransaction 中执行的插入语句。 Select IDENT_CURRENT('tableName') 是在事务之后完成的。

我做错了什么?

更新

我的插入语句是由基类动态构建的:

INSERT INTO TEST (NAME) VALUES (@Name)

该命令的参数集合的值为“xxx”,并且一切都很好地插入到表中。

我不使用存储过程,只使用纯 SqlDataReader 和 C#。

commandText = "INSERT INTO TEST (NAME) VALUES ('Test1');Select Scopy_Identity();"

我如何才能获得运行上述语句的最后一个自动 inc id,我应该为上述语句调用 ExecuteNonQueryExecuteReader,因为它有一个 INSERTSELECT,这令人困惑......

【问题讨论】:

  • 向我们展示您的插入命令。看看我上周对类似问题的回答,也许会有所帮助:stackoverflow.com/questions/9319532/…您必须在同一范围内使用 scope_identity。
  • 你可能完全独立地执行了这两个命令。
  • 我独立执行它们。
  • 那么SCOPE_IDENTITY() 将不起作用 - 它们必须在同一范围内(因此得名)。使用存储过程将生成的 ID 作为输出参数发回,然后您可以将其保留在会话中或任何地方,以便以后引用它。
  • @Pascal 那么您如何期望 SCOPE 身份从不同的范围中提取身份?出于非常明确的原因,它被称为 SCOPE 身份......

标签: sql-server scope-identity


【解决方案1】:

IDENT_CURRENT 返回为任何会话和任何范围内的特定表生成的最后一个标识值。

@@IDENTITY 返回为当前会话中的任何表在所有范围内生成的最后一个标识值。

SCOPE_IDENTITY 返回为当前会话和当前范围内的任何表生成的最后一个标识值。

【讨论】:

    【解决方案2】:

    只需使用OUTPUT Clause (Transact-SQL),您就可以在同一语句中插入数据并选择返回所有(甚至多个)身份:

    INSERT INTO TEST (NAME) OUTPUT INSERTED.YourIdentity VALUES (@Name)
    

    工作示例:

    DECLARE @YourTable table (YourIdentity int identity(1,1) primary key, YourCol1 varchar(5))
    
    INSERT INTO @YourTable (YourCol1) OUTPUT INSERTED.YourIdentity VALUES ('ABC')
    

    输出:

    YourIdentity
    ------------
    1
    
    (1 row(s) affected)
    

    【讨论】:

    • 如果变量不被重用,则不需要读取变量中的最后一行 id。我认为您的场景在存储过程中更有意义。但它的工作原理与 Scope_Identiy 相同,因此我将其标记为解决方案,尽管我不使用它;-)
    • 我的示例没有将身份放入变量中! “工作示例”代码创建了一个变量表,因此可以插入一行并生成一个标识。 OUTPUT INSERTED.YourIdentity 导致插入语句生成一个包含插入的标识值的结果集。此解决方案使用单个 INSERT 来插入数据并选择标识值。您在 cmets 中的解决方案使用两个命令来实现相同的目的。如果在插入中使用 OUTPUT,则可以消除 ;Select Scopy_Identity(); 代码。
    • 请注意,如果表有插入触发器,这将给出错误。然后你需要使用OUTPUT INTO 而不仅仅是OUTPUT
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 2013-05-22
    • 2021-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多