经典ASP断开连接的记录集问题

问题描述:

因此,我被要求更新旧的经典ASP网站。它没有使用参数化查询,输入验证也很少。为了简化事情,我编写了一个帮助函数,该函数打开与数据库的连接,使用任何参数设置命令对象,并创建一个断开连接的记录集[我认为!?! :)]下面的代码:经典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(),然后不填充返回的记录。这让我怀疑记录集是否确实断开连接。如果我评论一切正常,一切正常。在设置ActiveConnection = Nothing之前和之后,我还在使用discRS值的函数中做了一些Response.Write(),并正确地返回记录集值。所以它似乎被隔离到discRS.Close()

我在4guysfromrolla.com上发现了一篇旧文章,它在该函数中发布了记录集Close()。我在其他网站上看到过同样的情况。我不确定这是否是一个错误,或者如果有什么改变?

注:我使用的是内置到Visual Studio Express的2013

+0

您也可以使用getRows()并将记录集分配给内存中的变量。请参阅:http://*.com/questions/8916384/asp-getrows-count –

+1

Diodeus,可能,但我必须记住什么元素是在什么位置,而不是只使用列名作为索引。 – Sam

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

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

由于代码中已经有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 

为了避免这一切的麻烦,你可以有函数返回“真正的”断开连接的记录由复制所有的数据到新创建的记录。如果相关让我知道,我会带一些代码。

+0

+1例如在使用它之后关闭RecordSet。不知道关于摆脱这3个特定代码行的建议。我同意删除'disc.Close()',但如果我留下其他两个代码片段,一切仍然有效。我宁愿过度清理,也不愿意发生内存泄漏。 – Sam

+0

奇怪的是,VBScript是一个真正的谜,然后如果它仍然工作后,您将对象设置为无。干杯! :) –

+0

我很想看到将数据复制到新创建的记录集的代码! –

在你的代码中,我可以看到IIS快递:

​​

所以,这个记录是不是已经关闭?

+0

不,记录集没有关闭,但它与连接断开。我最好的猜测是'Set GetDiscRS = discRS'可能是通过引用完成的,而不是创建一个副本;所以'GetDiscRS'和'discRS'都指向内存中的同一个对象。因此'discRS.Close()'可能最终不仅会清空'discRS',而且'GetDiscRS'返回值。只是想知道为什么我发现的例子都是关闭函数中的记录集。 – Sam

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

您可以清理任何连接和命令对象,但为了让您的记录集返回填充,您不需要关闭它或将其丢弃。

您的代码应该这样结束:

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

他确实使用断开连接的记录。我开始在VB6中使用它们。你设置connection = Nothing,你基本上有一个集合类,它具有记录集中所有方​​便的方法(即排序,查找,过滤等)。另外,您只需保存连接以获取记录所需的时间,所以当微软通过连接授权他们的服务器时,这是一个很好的方法,可以最大限度地减少同时连接多少个用户。

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

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