为什么@@ IDENTITY或SCOPE_IDENTITY()是DBNull?

时间:2009-01-10 23:21:37

标签: sql vb.net identity

(已解决:见底部)

我有以下代码段:

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'类型无效。”关于什么可能导致这个值为null的任何想法?我没有在表上设置任何触发器,我的查询唯一做的就是在1个表中运行普通插入。

修改:根据此处的建议,我添加了affected参数。我设置了一个断点,并且受影响= 1但我仍然有例外。但是,我在SELECT @affected之前发现我有SELECT @newID。我切换了顺序,现在@affected = 0.所以看来我的插入语句出现了问题。谢谢你的帮助!

7 个答案:

答案 0 :(得分:8)

来自MSDN

  

INSERT,SELECT INTO或bulk之后   复制声明完成,   @@ IDENTITY包含最后一个身份   由...生成的值   声明。如果声明没有   影响任何具有身份的表   列,@ @ IDENTITY返回NULL。

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

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

从触发器过程中检索id

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

答案 1 :(得分:4)

在99.9%的案例中,您应该使用SCOPE_IDENTITY()作为@@IDENTITY的反对者。您的情况非常罕见,需要SCOPE_IDENTITY()

以外的其他情况
  

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

     

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

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

答案 2 :(得分:2)

各种可能性:

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

  • 您的陈述(未显示)插入 各种表,最后​​一个 没有身份 柱

  • INSERT触发一个触发器 插入到没有的表 标识栏 - 试试 SCOPE_IDENTITY()改为

答案 3 :(得分:1)

您可能需要检查@@ ROWCOUNT> 0

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

答案 4 :(得分:1)

另一次发生这种情况,改变

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

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

为我解决了这个问题。看来我的主持人提出了更明确的声明要求。

答案 5 :(得分:0)

query text...部分是什么?我猜是INSERT。 可能是insert ... select找不到任何行吗?

答案 6 :(得分:0)