是这样的,有一个执行sql语句返回记录集的函数,在函数的最后是将recordset释放。我的问题是释放后还可以将值付出去吗?还有一个问题是如果在释放之前加上close则会出错。不知为啥。那位仁兄指点下。
代码如下:Public Function ExecuteSQL(ByVal SQL As String, MsgString As String) As ADODB.Recordset
'executes SQL and returns Recordset
   Dim cnn As ADODB.Connection
   Dim rst As ADODB.Recordset
   Dim sTokens() As String
   
   On Error GoTo ExecuteSQL_Error
   
   sTokens = Split(SQL)
   Set cnn = New ADODB.Connection
   
   cnn.Open ConnectString
   
   If InStr("INSERT,DELETE,UPDATE", UCase$(sTokens(0))) Then
      cnn.Execute SQL
      MsgString = sTokens(0) & " query successful"
   Else
      Set rst = New ADODB.Recordset
      rst.Open Trim$(SQL), cnn, adOpenKeyset, adLockOptimistic
      'rst.MoveLast     'get RecordCount
      Set ExecuteSQL = rst
      MsgString = "查询到" & rst.RecordCount & " 条记录 "
   End If
ExecuteSQL_Exit:
'将记录集对象直接释放后记录集呢?
   '如果有rst.close的话就会出错。
   Set rst = Nothing
   Set cnn = Nothing
   Exit FunctionExecuteSQL_Error:
   MsgString = "查询错误: " & Err.Description
   Resume ExecuteSQL_Exit
   
End Function下面是调用这个函数的一段代码:        txtSQL = "select * from user_Info where user_ID = '" & txtUserName.Text & "'"
        Set mrc = ExecuteSQL(txtSQL, MsgText)
        If mrc.EOF Then
            MsgBox "没有这个用户,请重新输入用户名!", vbOKOnly + vbExclamation, "警告"
            txtUserName.SetFocus
        end if

解决方案 »

  1.   

    如果ExecuteSQL内部执行没有触发错误的话,
    在Set rst = Nothing之前会执行Set ExecuteSQL = rst,这样就不会有问题,函数外边照样可以操作这个记录集。
    至于rst.close出错,大概是执行SQL的时候出错了,跳转到了这一句,或者执行的是"INSERT,DELETE,UPDATE"语句,记录集并没有打开,然后close就出错了。
    因为你还要在函数外面操作这个记录集,所以你根本不应该关闭它,close语句本身就多余,不应该存在。
      

  2.   

    1、楼主您的是类模块(引用'Microsoft Activex Data Objects 2.1(或以上) Library),rst.close出错,是因为该类模块是只是检查是否正常连接SQL(并以更新,添加,删除的功能打开)。
    例如以下(这样打开后才能使用RS.CLOSE关闭)
    '''''''''''''''''''''''''''''''''''
    引用'Microsoft Activex Data Objects 2.1(或以上) Library
    '''''''''''''''''''''''''''''''''''
    Dim rs As ADODB.Recordset
    Dim txtsql1 as string
    txtsql1 = "select * from db"
    Set rs = ExecuteSQL(txtsql1)
    If rs.EOF = True Then
    rs.Close'打开后才能使用关闭
    Set rs = Nothing
    exit sub
    end if
    ''''''''''''''''''''''''''''
    2、可以将值付出去的。(只要您在关闭和释放前赋值就可以)
    ...........................
    以上是个人见解,可能会存在错误的地方,希望对您有用。
      

  3.   

    如果那个close不添加的话是可以正常使用的,函数可以正常返回记录集。如果添加就会出现错误,不是函数内部的错误,如果是内部错误那在不添加close的情况下是不可能正确执行的。
      

  4.   


    直接释放和关闭在释放不一样吗?结果都是消除对象。如果添加close在下的那个地方  mrc.Eof 就会出错。
      

  5.   

    '如果有rst.close的话就会出错。If Not rst is Noting Then rst.Close
      

  6.   


    函数代码就是那个了。下面的那个就是调用这个函数的一段代码,如果在函数中那个注释的地方添加close的话,执行到if mrc.Eof then就出错
      

  7.   

    你的ExecuteSQL执行二类SQL语句,其中之一是INSERT等等更新语句,这类语句直接用的是cn.execute方法,是不用rst.open的,所以加上rs.close当然会错
      

  8.   


    Dim txtsql As String
    Dim MsgString As String
    Dim rs As ADODB.Recordset
     txtsql = "select * from [user_Info] where user_ID = '" & txtUserName.Text & "'"
        Set rs = ExecuteSQL(txtsql, MsgString)
         If rs.EOF Then
          MsgBox "没有这个用户,请重新输入用户名!", vbOKOnly + vbExclamation, "警告"
          txtUserName.SetFocus
          rs.Close
         Set rs = Nothing
      End If原因是楼主您没有对MsgString进行定义。
      

  9.   


    我往里传的时候是msgtext。定义过的。不是这个问题。
    问题是recordset 的close和nothing。
    四楼那位仁兄的最后一句户
    我觉得是问题所在。但是我不知道是为什么。既然已经将对象释放了,那么用close有什么不同。
      

  10.   


    Public Function ExecuteSQL(ByVal SQL As String, MsgString As String) As ADODB.Recordset
    'executes SQL and returns Recordset
       Dim cnn As ADODB.Connection
       Dim rst As ADODB.Recordset
       Dim sTokens() As String
       
       On Error GoTo ExecuteSQL_Error
       
       sTokens = Split(SQL)
       Set cnn = New ADODB.Connection
       
       cnn.Open connstring
       
       If InStr("INSERT,DELETE,UPDATE", UCase$(sTokens(0))) Then
          cnn.Execute SQL
          MsgString = sTokens(0) & " query successful"
       Else
          Set rst = New ADODB.Recordset
          rst.Open Trim$(SQL), cnn, adOpenKeyset, adLockOptimistic
          'rst.MoveLast     'get RecordCount
          Set ExecuteSQL = rst
          MsgString = "查询到" & rst.RecordCount & " 条记录 "
       End If
    ExecuteSQL_Exit:
    '将记录集对象直接释放后记录集呢?
       '如果有rst.close的话就会出错。
       Set rst = Nothing
       Set cnn = Nothing
       Exit Function
    ExecuteSQL_Error:
       MsgString = "查询错误: " & Err.Description
       Resume ExecuteSQL_Exit
    End Function
    Public Function connstring() As String
    connstring = " Provider=SQLOLEDB.1;Persist Security Info=False;Initial Catalog=数据库名称;User ID=sa;password=;Data Source=192.168.0.1"
    End Function
    Dim txtsql As String
    Dim MsgText As String
    Dim rs As ADODB.Recordset
     txtsql = "select * from [user_Info] where user_ID = '" & txtUserName.Text & "'"
            Set rs = ExecuteSQL(txtsql, MsgText)
            If rs.EOF Then
                MsgBox "没有这个用户,请重新输入用户名!", vbOKOnly + vbExclamation, "警告"
                txtUserName.SetFocus
                rs.Close
                Set rs = Nothing
            End If以上在VB6。0和SQL2000通过测试。
      

  11.   

    我的程序本来就没有错误。
    我的问题是 那个close还有就是记录集释放后记录集是否可用的问题。
    焦点在那个recordset
      

  12.   

    close是关闭以open方式打开的记录集,也就是open和close是配对的,当你的函数只执行cn.execute方法时,记录集没有open,所以这时close必然出错,如果你想加上close,那么:
    if rs.state=adstateopen then rs.closeset rs=nothing 是将对象变量rs从实际对象中分离开来,通俗的理解分离以后这个rs相当于一个没有赋值的变量,当然不能再如你说的“将值付出去”...
      

  13.   

    你这个函数中,rs.close不是必须的
    而 set rs=nothing 是个好习惯
    过程中的所有变量和对象,随你这个过程的完成,全部都会销毁..... 
      

  14.   


    Public Function ExecuteSQL(ByVal SQL As String, MsgString As String) As ADODB.Recordset
    'executes SQL and returns Recordset
       Dim cnn As ADODB.Connection
       Dim rst As ADODB.Recordset
       
       '定义一个数组用来存放字符串的第一个词
       Dim sTokens() As String
       
       On Error GoTo ExecuteSQL_Error
       
       sTokens = Split(SQL)             '给数组赋值
       Set cnn = New ADODB.Connection                '连接对象实例化
       cnn.Open ConnectString           '打开连接      Set rst = New ADODB.Recordset        '创建新的记录集。
          rst.Open Trim(SQL), cnn, _
             adOpenKeyset, _
             adLockOptimistic                               '打开记录集
          'rst.MoveLast     'get RecordCount
          Set ExecuteSQL = rst
          MsgString = "查询到" & rst.RecordCount & _
             " 条记录 "ExecuteSQL_Exit:
    '    If rst.State = adStateOpen Then rst.Close加上这个会出错!出错位置为下端代码的mrc.Eof
       Set rst = Nothing
       Set cnn = Nothing
       Exit Function
       
    ExecuteSQL_Error:
       MsgString = "查询错误: " & _
          Err.Description
       Resume ExecuteSQL_Exit     '指定的 行 处恢复运行
    End Function
    下面还是调用这个函数的代码:        txtSQL = "select * from user_Info where user_ID = '" & txtUserName.Text & "'"
            Set mrc = ExecuteSQL(txtSQL, MsgText)
            If mrc.EOF Then
                MsgBox "没有这个用户,请重新输入用户名!", vbOKOnly + vbExclamation, "警告"
                txtUserName.SetFocus
            end if
      

  15.   

    哦,仔细看了下,我明白楼主的意思了,sorry上面的说法有问题...
    这个函数是返回一个记录集:
    Set ExecuteSQL = rst
    所以rst不能close,不然会影响到ExecuteSQL这个记录集
    rst可以nothing,这样rst从实际的记录集对象中分离出来了,不会影响ExecuteSQL这个记录集
      

  16.   

    ExecuteSQL这个记录集是rst的缓存对象,所以当rst的变动会影响到ExecuteSQL这个记录集,包括rst.close...而set rst=nothing后,rst就从实际对象中分离出来了,而通过rst对象创建的对象都将被孤立。这些已缓存对象的任何属性依然可用....