(解决方案:见底部)
我有以下代码片段:
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表中运行一个普通的insert。
编辑:根据这里的建议,我添加了一个affected参数。我设置了一个断点,并影响=1,但我仍然得到了异常。但是,我发现在选择“受影响”之前,我已经选择了“newID”。我改变了顺序,现在@affected = 0。所以这似乎是我的insert语句的一个问题。谢谢你的帮忙!
发布于 2009-01-10 23:36:14
来自MSDN
在完成INSERT、SELECT INTO或批量复制语句之后,@@IDENTITY包含语句生成的最后一个标识值。如果语句不影响任何带有标识列的表,@@IDENTITY将返回NULL。
是否检查插入是否成功?您要插入的记录可能由于某种原因而无法插入,因此id为null。
表上有设置触发器吗?您可能正在使用@@IDENTITY从触发器过程检索id。
我建议使用身份()或输出参数来获取id。
发布于 2009-01-11 00:19:01
在99.9%的情况下,您应该使用SCOPE_IDENTITY()作为相对于@@IDENTITY的方法。这是非常罕见的情况,你会有需要其他东西,而不是SCOPE_IDENTITY()
@@IDENTITY返回在连接上产生的最后一个标识值,不管产生值的表是什么,也不管产生值的语句的范围。如果在表上有一个触发器,导致在另一个表中创建标识,则将得到最后创建的标识,即使是创建该标识的触发器。SCOPE_IDENTITY()返回在连接上产生的最后一个标识值,并返回同一作用域中的语句,而不管生成该值的表是什么。SCOPE_IDENTITY()和@@IDENTITY一样,将返回在当前会话中创建的最后一个标识值,但也会将其限制在当前范围内。
您确定该表上没有审计触发器(可能是由您的DBA添加的)吗?
发布于 2009-01-10 23:31:46
各种可能性:
https://stackoverflow.com/questions/431955
复制相似问题