我有一个在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
答案 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