【问题标题】:Why would @@IDENTITY or SCOPE_IDENTITY() be DBNull?为什么@@IDENTITY 或 SCOPE_IDENTITY() 会是 DBNull?
【发布时间】:2014-03-12 09:33:54
【问题描述】:

(已解决:见底部)

我有以下代码sn-p:

Protected Sub SqlDataSource1_Inserted(ByVal sender As Object, 
ByVal e As System.Web.UI.WebControls.SqlDataSourceStatusEventArgs)
Handles SqlDataSource1.Inserted
    affected = CInt(DirectCast(e.Command.Parameters("@affected"), IDbDataParameter).Value)
    newID = CInt(DirectCast(e.Command.Parameters("@newID"), IDbDataParameter).Value)
End Sub

@newID 在 SQL 字符串中的定义如下:

"INSERT INTO x(a,b,c) VALUES (@a,@b,@c); SELECT @affected = @@rowcount, @newID = SCOPE_IDENTITY();

使用 ASP.NET 定义的参数如下:

奇怪的是,它在 90% 的时间里都有效,但每隔一段时间它就会抛出一个 InvalidCastException,说“从类型 'DBNull' 到类型 'Integer' 的转换无效。”关于什么可能导致该值为空的任何想法?我没有在表上设置任何触发器,我的查询唯一要做的就是将普通插入运行到 1 个表中。

编辑:根据此处的建议,我添加了一个affected 参数。我设置了一个断点,并影响 = 1,但我仍然得到了异常。但是,然后我发现我在 SELECT @affected 之前有 SELECT @newID。我切换了顺序,现在@affected = 0。所以这似乎是我的插入语句的问题。感谢您的帮助!

【问题讨论】:

  • 目标表上是否有触发器?
  • 您需要发布整个查询。
  • 发生错误时,该行是否被插入到表中??
  • @amdfan - 我认为您在 SQL 字符串中设置 @@ROWCOUNT 的方式存在问题;它将返回 1,因为它是一个全局变量,并将引用最后一条语句,即 SELECT @newID = @@IDENTITY。简单的分配将返回 1 ...
  • 啊,你现在已经编辑了你的 SQL 字符串了!

标签: sql vb.net identity


【解决方案1】:

来自MSDN

在 INSERT、SELECT INTO 或批量之后 副本声明完成, @@IDENTITY 包含最后一个身份 所产生的价值 陈述。如果声明没有 影响任何具有身份的表 列,@@IDENTITY 返回 NULL。

您是否有检查插入是否成功?您尝试插入的记录可能由于某种原因无法插入任何内容,因此 id 为空。

桌子上是否设置了触发器?您可能正在使用 @@IDENTITY

从触发过程中检索 id

我建议使用SCOPE_IDENTITY()output parameter 来获取id

【讨论】:

【解决方案2】:

在 99.9% 的情况下,您应该使用 SCOPE_IDENTITY() 而不是 @@IDENTITY。您很少会遇到需要SCOPE_IDENTITY()以外的其他内容的情况

@@IDENTITY 返回最后一个 IDENTITY 连接产生的价值, 不管产生的表 价值,无论范围如何 产生的声明 价值。如果你有一个触发器 导致身份成为的表 在另一个表中创建,你会得到 最后创建的身份, 即使这是触发 创建它。

SCOPE_IDENTITY() 返回在 a 上生成的最后一个 IDENTITY 值 连接并通过在 范围相同,与表无关 产生了价值。 SCOPE_IDENTITY(),如@@IDENTITY, 将返回最后一个标识值 在当前会话中创建,但它 也会将其限制在您当前的 范围也是如此。

您确定该表上没有审计触发器(可能由您的 DBA 添加)?

【讨论】:

    【解决方案3】:

    各种可能性:

    • INSERT 不插入任何内容(如 erikkallen 说)

    • 您的声明(未显示)插入 到各种桌子,最后一张 没有身份的 专栏

    • INSERT 触发一个触发器,该触发器 插入到没有 身份列 - 尝试 SCOPE_IDENTITY() 代替

    【讨论】:

      【解决方案4】:

      您可能需要检查@@ROWCOUNT 是否 > 0。

      在过去的 SQL Server 版本中也存在影响@@IDENTITY 生存能力的触发器的已知问题。你有什么触发器吗?

      【讨论】:

      • 不,没有触发器。不过还是谢谢。
      【解决方案5】:

      又一次发生这种情况,正在改变

      <asp:Parameter Name="newID" Direction="Output" Size="4" />
      

      <asp:Parameter Name="newID" Direction="Output" Type="Int32" Size="4" />
      

      为我解决了这个问题。看来我的主持人开启了一些更明确声明的要求。

      【讨论】:

        【解决方案6】:

        query text... 部分是什么?一个插入,我猜。 会不会是一个没有找到任何行的insert ... select

        【讨论】:

          【解决方案7】:
          猜你喜欢
          • 2010-12-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-22
          • 1970-01-01
          相关资源
          最近更新 更多