ADO记录集在按顺序传递给多个函数时丢失其数据(访问VBA)

时间:2011-11-07 17:00:06

标签: oracle vba ado

我有一个返回ADO记录集的函数,后者又用于提供后续函数。它第一次传递给其中一个函数,运行正常;但在下一个函数中,记录集位于EOF。我假设我的记录集已被传递By Ref,所以尝试使用MoveFirst:这给了我一个错误,因为游标类型默认为只转发。

我尝试了以下内容:

  • 将参数设置为By Val;这没有效果。
  • 创建了记录集的副本,并在第一个函数中使用原始文件,在第二个函数中使用副本;仍然是同样的问题(第二个是说EOF,这意味着它是空的而不是EOF;我无法想象两个记录集以某种方式连接,但也许)。
  • 更改了我的数据库代码以使用不同的游标类型(adOpenStatic):这实际上对我的应用程序更正确,但它给出了非常奇怪的结果。也就是说,在更改之前工作正常的查询中,第一个字段未被返回!这很重要,所以我不能继续这条路。

有什么想法吗?


主数据库查询功能:GetData。获取SQL和varchar参数列表(如果有)并返回记录集。它引用dbOpen,它只是用提供的凭据打开连接。

Private Function GetData(ODBC As DBConnection, ByVal QuerySQL As String, Optional Parameters As Collection) As ADODB.Recordset
    Dim DB As ADODB.Connection
    Dim Query As ADODB.Command
    Dim Parameter As ADODB.Parameter

    Set DB = New ADODB.Connection

    If dbOpen(DB, ODBC) Then
        Set Query = New ADODB.Command
        Query.ActiveConnection = DB
        Query.CommandText = QuerySQL

        If Not Parameters Is Nothing Then
            For Each param In Parameters
                Set Parameter = Query.CreateParameter(, adVarChar, adParamInput, Len(param), param)
                Query.Parameters.Append Parameter
            Next
            Set Parameter = Nothing
        End If

        Set GetData = Query.Execute

        ' Uncommenting this seems to reset the data in GetData...
        ' A bit of a memory leak, but we assume VBA will take care of it :P
        'dbClose DB
    Else
        MsgBox "Cannot connect to the database.", vbExclamation
        Set GetData = Nothing
    End If
End Function

然后我做了这样的事情:

Dim myRecords as ADODB.Recordset

' For the sake of argument, we assume this returns a nontrivial recordset
Set myRecords = GetData(someDSN, someSQL, someParameters)

Debug.Print myRecords.EOF ' Returns False

ID = writeHeader(myRecords)

Debug.Print myRecords.EOF ' Returns True

writeData ID, myRecords   ' Breaks because at EOF

writeHeader函数将使用MoveNext遍历记录集中的每条记录。但是,如果我按值传递myRecords或作为副本传递,那么我们仍会遇到EOF问题。如果我在MoveFirst中的记录迭代代码末尾添加writeHeader,它会抱怨我无法移动到这样的记录集的开头。如果我更改了GetData功能,以便将Set GetData = Query.Execute更改为:

Set GetData = New ADODB.Recordset

GetData.CursorType = adOpenStatic
GetData.Open Query

然后,当我的代码中的查询运行时 - 它没有改变 - 第一个字段不是记录集的一部分(!?)比如说,myRecords!ID是第一个字段:如果引用了这个,我会收到一条警告:该项不是记录的成员(并且它也不是枚举成员;因此myRecords.Fields(1)只返回查询中的下一个字段。)< / p>

1 个答案:

答案 0 :(得分:1)

通过@TimWilliams的有用提示,我通过将GetData函数更改为以下内容来解决此问题:

Private Function GetData(ODBC As DBConnection, ByVal QuerySQL As String, Optional Parameters As Collection) As ADODB.Recordset
    Dim DB As ADODB.Connection
    Dim Query As ADODB.Command
    Dim Parameter As ADODB.Parameter
    Dim Output As ADODB.Recordset

    Set DB = New ADODB.Connection

    If dbOpen(DB, ODBC) Then
        Set Query = New ADODB.Command
        Query.ActiveConnection = DB
        Query.CommandText = QuerySQL

        If Not Parameters Is Nothing Then
            For Each param In Parameters
                Set Parameter = Query.CreateParameter(, adVarChar, adParamInput, Len(param), param)
                Query.Parameters.Append Parameter
            Next
            Set Parameter = Nothing
        End If

        Set Output = New ADODB.Recordset
        Output.CursorType = adOpenStatic
        Output.CursorLocation = adUseClient
        Output.Open Query
    Else
        MsgBox "Cannot connect to the database.", vbExclamation
        Set Output = Nothing
    End If

    Set GetData = Output
End Function

然后,在通过记录集进行游说之前,我使用MoveFirst