下面这个函数中:
 
Public Function SelectSQL(ByVal SQLStr As String, ByRef msg As String) As ADODB.Recordset 
'执行SQL语句,并ADODB.Recordset返回给 SELECTSQL 
    Dim Conn As ADODB.Connection 
    Dim rst As ADODB.Recordset 
    Dim sTokens() As String 
    '出错处理 
    On Error GoTo ErrorHandle 
    '判断SQL语句 
    sTokens = Split(SQLStr) 
    If InStr("SELECT", UCase((sTokens(0)))) Then 
        '打开数据库连接 
        If OpenConn(Conn) Then                      '如果打开连接成功,就进行查询操作 
            Set rst = New ADODB.Recordset 
            rst.CursorLocation = adUseClient 
            rst.Open Trim$(SQLStr), Conn, adOpenDynamic, adLockOptimistic    '执行查询操作 
            Set SelectSQL = rst 
            msg = "查询到" & rst.RecordCount & " 条记录! " 
        End If 
    Else 
        msg = "SQL语句有误:" & SQLStr 
    End If 
Finally_Exit: 
    Set rst = Nothing 
    Set Conn = Nothing 
    Exit Function 
ErrorHandle:        '如果SQL语句执行出错,提示出错信息并转到Finally_Exit 
    MsgString = "查询错误: " & Err.Description 
    Resume Finally_Exit 
End Function 问题如下: 
1、Set SelectSQL = rst  作用是什么?(是引用,还是将RST的记录集复制一份给SELECTSQL,还是其他?) 
2、Finally_Exit: 
    Set rst = Nothing 
    Set Conn = Nothing 
  以上二句执行完后,变量RST和CONN不是被注销了吗,即使不是这样,这两个变量是两个局部变量,函数一执行完,不也消失了吗。
   SelectSQL岂不是什么也没有了? 这个函数怎么能返回一个ADODB.Recordset。

解决方案 »

  1.   

    这个过程类似于张三(rst)递给李四(SelectSQL)一件东西。
    过程:
    张三递,李四接 (Set SelectSQL = rst)
    然后张三松手    (Set rst = Nothing)
    只要李四接住了东西,张三就可以去死了。
      

  2.   

    是不是说在
            Set rst = New ADODB.Recordset 
            rst.CursorLocation = adUseClient 
            rst.Open Trim$(SQLStr), Conn, adOpenDynamic, adLockOptimistic    '执行查询操作 
    第三句执行之后CONN就没有用了,可以注销了?
      

  3.   

    对呀,只要后面没有再调用到conn和rst,就可以注销
      

  4.   

    对于对象的赋值,需要使用Set语句。
    并且对象使用完之后,要关闭(有关闭的,如记录集),并且销毁,否则会出现内存泄漏。
    虽然函数执行完,对象生存期已过,但是不会自动销毁的。
      

  5.   

    以上的这函数应该不能正常使用。
    假设有一个函数调用
    dim rs as adodb.recordset
    dim imsg as string
    set rs = SelectSQL("select * from db",imsg)
    msgbox imsg 
    do while not rs.eof
       msgbox rs.fields(0).value
       rs.movenext
    loop
    执行的时候肯定会出错。因为本地rs需要的宿主都已经“去死了”
    除非在函数里用
    set SelectSQL = rst.clone()
    将rst脱机到本地才能正常使用
      

  6.   

    建议楼主在
        Set rst = Nothing 
        Set Conn = Nothing 
    前加上rst.Close
    Conn.Close我的意思是避免循环引用导致COM不能释放
      

  7.   

    Set SelectSQL = rst
    VB 中,函数返回值就是一个与函数同名的变量。
    这句语句就是将 rst 赋给返回值变量,对象的赋值都是引用,这时变量 rst 和 SelectSQL 都引用同一个 RecordSet 对象实例。[code=VB]Finally_Exit: 
        Set rst = Nothing 
        Set Conn = Nothing 
    分别断开变量 rst 和 Conn 与对象实例的引用,按照标准的术语是减少对象实例的引用计数。
    不过由于 RecordSet 对象实例被 SelectSQL 变量引用,而 Connection 对象又被 RecordSet 对象引用,按照规则,被引用的对象(引用计数非零)的对象不释放——即这两句语句并不会产生注销。
    同样,即使不写这两句,过程结束是也一样会断开引用,不过效果一样,也不会注销。