送分100分:记录集的生存周期问题。
Public Function GetConnStr() As String ' 得到数据库连接字符串,用户可以在此处设置连接字符串
GetConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\A.mdb;…. "
End Function
Public Function OpenConn(ByRef Conn2 As ADODB.Connection) As Boolean '打开数据库连接,连接成功返回true,出错时返回false
Set Conn2 = New ADODB.Connection
Conn2.Open GetConnStr
OpenConn = True
End Function
Public Function GetRst(ByVal SQL As String, ByRef msg As String) As ADODB.Recordset '执行SQL语句,返回ADODB.Recordset
Dim Conn2 As ADODB.Connection , Rst As ADODB.Recordset , sTokens() As String
If OpenConn(Conn2) Then
Set Rst = New ADODB.Recordset
Rst.CursorLocation = adUseClient
Rst.Open SQL, Conn2, adOpenDynamic, adLockOptimistic'取得记录集
Set GetRst = Rst '将取得的记录集
End If
Finally_Exit:
Set Rst = Nothing
Set Conn2 = Nothing
Exit Function
ErrorHandle:
msgstring = "查询错误: " & err.Description
MsgBox msgstring
Resume Finally_Exit
End Function
以上程序中:
Rst.Open SQL, Conn2, adOpenDynamic, adLockOptimistic'取得记录集
Set GetRst = Rst '将取得的记录集赋值给GetRst
Finally_Exit:
Set Rst = Nothing 'RST对象被销毁,那GETRST的值还有用吗,再就是RST是一个临时变量,取得的记录集是不是随之消失。 GETRST还能返回记录吗?
Set Conn2 = Nothing '
[解决办法]
rst是过程级对象变量,即使不显式的nothing,也会在这个过程结束后自动的消,所以只要不用close方法:
Set GetRst = Rst
Set Rst = Nothing
Set Conn2 = Nothing
这样写完全没有问题,不会影响GetRst的存在....
[解决办法]
1、RST对象被销毁,那GETRST的值还有用吗?
2、再就是RST是一个临时变量,取得的记录集是不是随之消失?
3、GETRST还能返回记录吗?
1、从你的程序看Set Rst = Nothing即GETRST= Nothing 它们是同一个东西。
2、是。
3、不能。
[解决办法]
Set Rst = Nothing作用就是将对象变量Rst与实际对象分离,与对象变量GetRst无关...
对象变量也是变量,楼主这个过程最通俗的可以如下理解:
function fun() as long
dim a as long
a=100
fun=a
end function
这个过程完成,fun=100,但过程级变量a已经不存在了....
[解决办法]
那当然实际代码测试出的结果更权威一些啦. 你想点办法设计一个测试用例啦. 我的理解这里就是一个引用计数的问题啦,用一面镜子来比喻反而觉得难以理解.
[解决办法]
dim rst as adodb.recordset '声明一个记录集对象
set rst=new adodb.recordset '实例化一个记录集对象,也就是对象变量rst引用 了一个实际对象,引用计数1
'.....
set GetRst=rst 'GetRst引用了一个实际对象,实际对象引用计数2
set rst=nothing '引用-1
[解决办法]
对象实例和对象变量的概念不清!
一个实例可以被多个变量引用(包括其他实例中的内部变量),只有所有解除了变量对实例的引用(引用计数归0),实例才会被释放。
这里有两个实例
甲 : New ADODB.Connection
乙 : New ADODB.Recordset
- VB code
Public Function GetRst(ByVal SQL As String, ByRef msg As String) As ADODB.Recordset Dim Conn2 As ADODB.Connection, Rst As ADODB.Recordset, sTokens() As String If OpenConn(Conn2) Then '通过函数调用,变量 Conn2 引用实例 甲' Set Rst = New ADODB.Recordset '变量 Rst 引用新创建的实例 乙' Rst.CursorLocation = adUseClient Rst.Open SQL, Conn2, adOpenDynamic, adLockOptimistic '打开记录后,实例 乙 的内部会对实例 甲 有引用' Set GetRst = Rst '(函数返回值)变量 GetRst 引用实例 乙' End IfFinally_Exit: Set Rst = Nothing '解除 Rst 对实例 乙 的引用' Set Conn2 = Nothing '解除 Conn2 对实例 甲 的引用' Exit Function '由于 GetRst 引用实例 乙,所以 乙 不释放' '又由于 乙 引用实例 甲,所以 甲 也不释放' ErrorHandle: msgstring = "查询错误: " & Err.Description MsgBox msgstring Resume Finally_ExitEnd Function