所以,我被要求更新旧的经典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
答案 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