经典ASP断开记录集问题

时间:2014-05-14 17:36:11

标签: vbscript asp-classic recordset

所以,我被要求更新旧的经典ASP网站。它没有使用参数化查询,并且输入验证很少。为了简化操作,我编写了一个帮助函数,它打开了与数据库的连接,设置了一个带有任何参数的命令对象,并创建了一个断开连接的记录集[我想!?! :)]这是代码:

Function GetDiscRS(DatabaseName, SqlCommandText, ParameterArray)

    'Declare our variables
    Dim discConn
    Dim discCmd
    Dim discRs

    'Build connection string
    Dim dbConnStr : dbConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
              "Data Source=" & rootDbPath & "\" & DatabaseName & ".mdb;" & _
              "Persist Security Info=False"

    'Open a connection
    Set discConn = Server.CreateObject("ADODB.Connection")
    discConn.Open(dbConnStr)

    'Create a command
    Set discCmd = Server.CreateObject("ADODB.Command")
    With discCmd
        Set .ActiveConnection = discConn
        .CommandType = adCmdText
        .CommandText = SqlCommandText

        'Attach parameters to the command
        If IsArray(ParameterArray) Then
            Dim cnt : cnt = 0
            For Each sqlParam in ParameterArray
                discCmd.Parameters(cnt).Value = sqlParam
                cnt = cnt + 1
            Next
        End If
    End With

    'Create the Recordset object
    Set discRs = Server.CreateObject("ADODB.Recordset")
    With discRs
        .CursorLocation = adUseClient     ' Client cursor for disconnected set
        .LockType = adLockBatchOptimistic
        .CursorType = adOpenForwardOnly
        .Open discCmd
        Set .ActiveConnection = Nothing   ' Disconnect!
    End With

    'Return the Recordset
    Set GetDiscRS = discRS

    'Cleanup
    discConn.Close()
    Set discConn = Nothing
    discRS.Close()                  ' <=== Issue!!!
    Set discRs = Nothing
    Set discCmd = Nothing
End Function

我的问题是,如果我在函数末尾调用discRS.Close(),则不会填充返回的记录集。这让我想知道记录集是否真的断开了。如果我评论该行,一切正常。我在设置Response.Write()之前和之后使用discRS值在函数中做了一些ActiveConnection = Nothing,并且它正确地返回了记录集值。因此它似乎与discRS.Close()隔离。

我在4guysfromrolla.com上找到了一篇旧文章,它在函数中发出了记录集Close()。我在其他网站上看过同样的事情。我不确定这是不是一个错误,或者是否有变化?

注意:我正在使用Visual Studio Express 2013中内置的IIS Express

5 个答案:

答案 0 :(得分:3)

据我所知,断开连接的记录集是指手动填充的记录集,而不是数据库,例如用作多维数组或哈希表类型。

所以你拥有的不是断开连接的记录集,因为它是从数据库中填充的,并且通过处理它的连接只会导致代码无法正常工作。

由于代码中已经有Set discConn = Nothing,因此您不必通过记录集或命令对象将其设置为空,它就是相同的连接对象。

总而言之,你应该完全摆脱代码中的以下几行:

  • Set .ActiveConnection = Nothing ' Disconnect!
  • discRS.Close() ' <=== Issue!!!
  • Set discRs = Nothing

然后,为了防止内存泄漏或数据库锁定问题,您应该在使用函数的代码中实际使用它之后关闭并处理记录集。

Dim oRS
Set oRS = GetDiscRS("mydatabase", "SELECT * FROM MyTable", Array())
Do Until oRS.EOF
    'process current row...
    oRS.MoveNext
Loop

oRS.Close ' <=== Close
Set oRS = Nothing ' <=== Dispose

为了避免所有这些麻烦,你可以使用函数return&#34; real&#34;通过所有数据复制到新创建的记录集中来断开记录集。如果相关,请告诉我,我会附上一些代码。

答案 1 :(得分:1)

在您的函数中,如果您希望将记录集返回到调用进程,则无法关闭并清理它。

您可以清理所有连接和命令对象,但是为了让您的记录集返回填充,您只需关闭它或处理它。

您的代码应该像这样结束:

    'Cleanup
    discConn.Close()
    Set discConn = Nothing
    'discRS.Close()
    'Set discRs = Nothing
    'Set discCmd = Nothing
end function

答案 2 :(得分:0)

在您的代码中,我可以看到:

Set .ActiveConnection = Nothing   ' Disconnect!

那么,这个Recordset还没有关闭?

答案 3 :(得分:0)

他确实使用了断开连接的记录集。我开始在VB6中使用它们。你设置connection = Nothing,你基本上有一个集合类,包含记录集的所有方便的方法(即排序,查找,过滤等等)。此外,您只需保留连接以获取记录所需的时间,因此当Microsoft通过连接许可其服务器时,这是最小化任何时候连接的用户数的好方法。

记录集完全正常,它只是没有连接到数据源。您可以重新连接它,然后应用对其进行的任何更改。

很久以前,似乎功能已被删除。

答案 4 :(得分:0)

您应该使用CursorLocation = adUseClient。然后你可以断开记录集。我创建了一个函数来将参数添加到命令字典对象,然后返回一个断开连接的记录集。

Function CmdToGetDisconnectedRS(strSQL, dictParamTypes, dictParamValues)

               'Declare our variables
              Dim objConn
               Dim objRS
               Dim Query, Command
               Dim ParamTypesDictionary, ParamValuesDictionary


               'Open a connection
               Set objConn = Server.CreateObject("ADODB.Connection")
               Set objRS = Server.CreateObject("ADODB.Recordset") 
               Set Command = Server.CreateObject("ADODB.Command")
               Set ParamTypesDictionary = Server.CreateObject("Scripting.Dictionary")
               Set ParamValuesDictionary = Server.CreateObject("Scripting.Dictionary")
               Set ParamTypesDictionary = dictParamTypes
               Set ParamValuesDictionary = dictParamValues
               Query = strSQL
               objConn.ConnectionString = strConn
               objConn.Open
               With Command
     .CommandText = Query
     .CommandType = adCmdText
     .CommandTimeout = 15

               Dim okey
               For Each okey in ParamValuesDictionary.Keys
                  .Parameters.Append .CreateParameter(CStr(okey), ParamTypesDictionary.Item(okey) ,adParamInput,50,ParamValuesDictionary.Item(okey))
               Next

                .ActiveConnection = objConn
           End With
               objRS.CursorLocation = adUseClient
               objRS.Open Command , ,adOpenStatic, adLockBatchOptimistic
               'Disconnect the Recordset
        Set objRS.ActiveConnection = Nothing

               'Return the Recordset
               Set CmdToGetDisconnectedRS = objRS     

               'Clean up...
               objConn.Close
               Set objConn = Nothing
               Set objRS = Nothing
               Set ParamTypesDictionary =Nothing 
    Set ParamValuesDictionary =Nothing
    Set Command = Nothing
End Function