我知道有关此问题的一些答案,但是我的问题与我拥有的特定代码段有关。
我正在尝试在VBA代码上执行的特定查询中插入最后一个插入的内容。这是要点:
Public Function Execute(cQry As excfw_dbQuery) As ADODB.Recordset
If pConn.State = 0 Then
OpenConnection
End If
qry = "INSERT INTO [some really long query, which actually works]; SELECT SCOPE_IDENTITY()"
On Error Resume Next
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open qry, pConn 'also tried with adOpenKeyset, adLockOptimistic
'some error handling code which is not related to the issue
Set rs = rs.NextRecordset() 'also tried without moving onto the next recordset
pInsertedId = rs.Fields(0).Value
Set Execute = rs 'this is just to pass the query result for SELECT queries
End Function
此代码应将最后插入的代码保存在pInsertedId变量中,但是每次插入一行时,我都会得到0。奇怪的是,当我将相同的代码复制并粘贴到SSMS中时,它可以正常工作。
我可能只是将一些唯一的数据插入到数据库的一些未使用的列中并进行查询,但是这个问题使我发疯,因为我记得几个月前我就开始工作了!
任何想法都会是什么问题?
-更新-
我刚刚注意到,在运行SELECT查询时,rs对象将保持打开状态,直到超出范围。这是观看部分的屏幕截图:
相反,在插入语句上,查询执行后立即关闭:
事实证明,我要插入的表具有多个触发器。因此,查询包含SELECT SCOPE_IDENTITY();实际上是第四个查询。为了获得正确的范围,我不得不向前移动4个查询。我如何以编程方式实现这一目标的方法如下。不是很干净(可能不是最好的方法),但是对我来说却很有效。
我基本上前进到下一个记录集,直到没有剩余记录为止,我通过检查错误号91(对象变量或未设置块变量的方式来检测该错误)
Public Function Execute(cQry As excfw_dbQuery) As ADODB.Recordset
If pConn.State = 0 Then
OpenConnection
End If
qry = "INSERT INTO [some really long query, which actually works]; SELECT SCOPE_IDENTITY()"
On Error Resume Next
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open cQry.Query, pConn, adOpenKeyset, adLockOptimistic
'some error handling code which is not related to the issue
On Error Resume Next
'begin loop
Do
'go to next recordset
Set rs = rs.NextRecordset()
'if we're getting error n. 91, it means
'recordsets are exhausted, hence we're getting
'out of the loop
If Err.Number = 91 Then
Err.Clear
Exit Do
End If
'if we are not out of recordsets, check the
'result of the query. If it is bigger then zero,
'it means we hit the jackpot.
If rs.Fields(0).Value > 0 Then
pInsertedId = rs.Fields(0).Value
End If
Loop
On Error GoTo 0
End Function
再次,不是最干净的方法,也不是最正确的方法,但是却成功了。我愿意接受任何改进或建议。