1

(已解决:见底部)

我有以下代码片段:

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

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

"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。所以这似乎是我的插入语句的问题。谢谢你的帮助!

4

7 回答 7

8

来自MSDN

在 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 包含该语句生成的最后一个标识值。如果该语句不影响任何具有标识列的表,则@@IDENTITY 返回 NULL。

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

桌子上是否设置了任何触发器?您可能正在使用 @@IDENTITY 从触发过程中检索 id

我建议使用SCOPE_IDENTITY()输出参数来获取 id

于 2009-01-10T23:36:14.423 回答
4

您应该在 99.9% 的情况下使用SCOPE_IDENTITY()as 相反。@@IDENTITY您很少会遇到需要其他东西的情况SCOPE_IDENTITY()

@@IDENTITY返回在连接上生成的最后一个 IDENTITY 值,与生成该值的表无关,也与生成该值的语句的范围无关。如果您在一个表上有一个触发器导致在另一个表中创建一个身份,您将获得最后创建的身份,即使它是创建它的触发器。

SCOPE_IDENTITY()返回连接上和同一范围内的语句生成的最后一个 IDENTITY 值,而不管生成该值的表是什么。SCOPE_IDENTITY() 与@@IDENTITY 一样,将返回在当前会话中创建的最后一个身份值,但它也会将其限制在您当前的范围内。

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

于 2009-01-11T00:19:01.297 回答
2

各种可能性:

  • INSERT 不插入任何东西(正如 erikkallen 所说)

  • 您的语句(未显示)插入到各种表中,其中最后一个没有标识列

  • INSERT 触发一个触发器,该触发器插入到没有标识列的表中 - 改为尝试 SCOPE_IDENTITY()

于 2009-01-10T23:31:46.900 回答
1

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

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

于 2009-01-10T23:41:24.633 回答
1

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

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

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

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

于 2010-01-05T02:52:23.467 回答
0

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

于 2009-01-10T23:25:32.030 回答
0

使用 SCOPE_IDENTITY() 和 @@IDENTITY 时,您可能会收到不正确的值。特别是当查询最终作为并行查询执行时:

http://support.microsoft.com/default.aspx?scid=kb;en-US;2019779

于 2011-03-29T11:58:35.767 回答