关于此问题,有一些答案,但是我的问题是关于我拥有的特定代码。
我正在尝试获取在VBA代码上执行的此查询的最后插入的ID。
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
这应该将最后插入的ID保存在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
再次,不是最干净的方法,也不是最正确的方法,但是却成功了。我愿意接受任何改进或建议。
您可以使用insert
子句显式保存output
语句的结果,并使用output
返回结果:
select
摘自qry =
"declare @Ids as ( Id Int );" +
"insert into MyTable ( Name ) " + ' Assuming Id is an identity column.
"output Inserted.Id into @Ids " +
"values ( @Name );" +
"select Id from @Ids;"
的文档:
INSERTED是列前缀,用于指定由插入或更新操作。前缀为INSERTED的列反映了UPDATE,INSERT或MERGE语句完成后的值,但在执行触发器之前。
您可以使用output
子句从行中获取任何数据(注意复数形式),例如新插入的行的标识列值。 output
可以与Output
,insert
,update
和delete
一起使用,并且在merge
的情况下可以访问before和after值。值得一放的工具。