SCOPE_IDENTITY回读

时间:2012-10-24 16:23:37

标签: sql-server-2008-r2

我有一个在Windows Server 2003和SQL Server 2000上运行多年的系统没有问题。最近我将系统迁移到了Windows Server 2008 R2和SQL Server 2008 R2,并开始出现一个非常奇怪的间歇性问题。

我在一个带有标识列的表中插入一行并执行select来检索标识值。大多数情况下,此代码工作正常,但随机间隔不返回标识。有时没有找到行,因此dr.Read返回false,有时我会返回一行,但其中没有标识列。我检查了数据库并且插入成功了,只是没有返回标识。桌子上没有触发器。

我也尝试将SQL更改为:

INSERT INTO test (value) 
VALUES (100) 
SELECT SCOPE_IDENTITY() AS 'identity' OPTION (MAXDOP 1) 

如果我遇到'max degree of parallelism'错误,但这也无济于事。

以下是相关代码(稍为简化说明):

Dim dr As SqlDataReader = Nothing
Dim objCommand As New SqlCommand
Dim oConn As New SqlConnection
Dim id as integer

oConn.ConnectionString = connStr 
oConn.open()

objCommand = New SqlCommand("INSERT INTO test (value) VALUES (100) SELECT SCOPE_IDENTITY() AS 'identity'", oConn, tr)

try
    dr = objCommand.ExecuteReader
    If Not dr.Read Then
        Throw (New Exception("Could not read IDENTITY"))
    Else
        id = dr("identity")
    End If
Catch
    Throw
Finally            
    If Not dr Is Nothing Then dr.Close()
    oConn.close()
End Try

2 个答案:

答案 0 :(得分:0)

如果您只是将它们作为两个单独的语句执行该怎么办?

objCommand = New SqlCommand("INSERT INTO test (value) VALUES (100); SELECT SCOPE_IDENTITY() AS 'identity'", oConn, tr)

SCOPE_IDENTITY为您提供“插入同一范围内的标识列的最后一个标识值。”

答案 1 :(得分:0)

SQL Server 2008 R2上的另一个选项是使用OUTPUT clause

INSERT INTO test (value) 
OUTPUT INSERTED.ID
VALUES (100) 

这将输出已插入行的ID - 这是您想要的标识值。

从您的代码中,如果您使用ID(而不是ExecuteScalar),则应该能够获取ExecuteReader,并且只需转换您返回的object类型int