SELECT SCOPE_IDENTITY()不返回最后插入的ID

问题描述 投票:0回答:1

我知道有关此问题的一些答案,但是我的问题与我拥有的特定代码段有关。

我正在尝试在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 statement

相反,在插入语句上,查询执行后立即关闭:

insert statement

excel-vba tsql adodb scope-identity
1个回答
0
投票

事实证明,我要插入的表具有多个触发器。因此,查询包含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

再次,不是最干净的方法,也不是最正确的方法,但是却成功了。我愿意接受任何改进或建议。

© www.soinside.com 2019 - 2024. All rights reserved.