经典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
据我所知,断开连接的记录集是指手动填充的记录集,而不是数据库,例如用作多维数组或哈希表的种类。
因此,你所拥有的不是断开连接的记录集,因为它是从数据库填充的,并且通过处理它的连接而导致代码无法正常工作。
由于代码中已经有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
为了避免这一切的麻烦,你可以有函数返回“真正的”断开连接的记录由复制所有的数据到新创建的记录。如果相关让我知道,我会带一些代码。
+1例如在使用它之后关闭RecordSet。不知道关于摆脱这3个特定代码行的建议。我同意删除'disc.Close()',但如果我留下其他两个代码片段,一切仍然有效。我宁愿过度清理,也不愿意发生内存泄漏。 – Sam
奇怪的是,VBScript是一个真正的谜,然后如果它仍然工作后,您将对象设置为无。干杯! :) –
我很想看到将数据复制到新创建的记录集的代码! –
在你的代码中,我可以看到IIS快递:
所以,这个记录是不是已经关闭?
不,记录集没有关闭,但它与连接断开。我最好的猜测是'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,你基本上有一个集合类,它具有记录集中所有方便的方法(即排序,查找,过滤等)。另外,您只需保存连接以获取记录所需的时间,所以当微软通过连接授权他们的服务器时,这是一个很好的方法,可以最大限度地减少同时连接多少个用户。
记录集是完全可用的,它只是没有连接到数据源。您可以重新连接它,然后应用对它所做的任何更改。
很久以前,似乎功能已被删除。
您也可以使用getRows()并将记录集分配给内存中的变量。请参阅:http://stackoverflow.com/questions/8916384/asp-getrows-count –
Diodeus,可能,但我必须记住什么元素是在什么位置,而不是只使用列名作为索引。 – Sam