PRB: Most ADO Recordset Properties Are Not Marshalled (185423)



The information in this article applies to:

  • ActiveX Data Objects (ADO) 1.5
  • ActiveX Data Objects (ADO) 2.0
  • ActiveX Data Objects (ADO) 2.1 SP2
  • ActiveX Data Objects (ADO) 2.5
  • ActiveX Data Objects (ADO) 2.6
  • ActiveX Data Objects (ADO) 2.7

This article was previously published under Q185423

SYMPTOMS

Most ActiveX Data Objects (ADO) Recordset properties such as STATUS and SOURCE are not marshalled between processes. In ADO 1.5, only a couple of underlying OLE DB properties of the rowset get marshalled with the rowset; DBPROP_IRowsetChange and DBPROP_IRowsetUpdate. When passing a recordset between processes, you primarily get the recordset data without any state.

In the case of the STATUS property, it should be noted that error based status codes originating from operations such as UPDATE, UPDATEBATCH, and so forth, are not preserved. Only the data is preserved.

The SOURCE property will be null when marshalling a recordset irrespective of what is set at the server.

RESOLUTION

You must return the Recordset state data, such as SOURCE and STATUS properties, explicitly in your own data structures. For example, if you call a method of a business object that returns a recordset, you would also create an argument of the method that can be used to return the state data.

STATUS

This behavior is by design.

MORE INFORMATION

Steps to Reproduce Behavior

  1. Write an OLE Out-of-process server (ActiveX EXE)in Visual Basic (VB) and add a method returning an ADO disconnected recordset and a method that updates the recordset. Before returning the recordset from the method, use another recordset object to modify one of the records held in the first recordset:
       ' Function to return a disconnected recordset.
       Public Function GetRcdSet() As Recordset
    
       Dim con As New Connection
       Dim rs1 As New Recordset, rs2 As New Recordset
       Dim newValue as String
       newValue = "Test Modified String"
    
       On Error GoTo ErrHandler
    
       con.Open "DSN=SQLServer;database=pubs", "sa"
       Set rs1.ActiveConnection = con
       rs1.CursorLocation = adUseClient
    
       ' Table1 is a table with the first column Varchar(255).
       rs1.Open "table1", , adOpenKeyset, adLockOptimistic, adCmdTable
    
       ' Check the value of Source property - should be "Table1".
       Debug.Print rs1.Source
       ' Disconnect recordset.
       Set rs1.ActiveConnection = Nothing
    
       Set GetRcdSet = rs1
    
       ' Modify one of the records.
       rs2.Open "table1", con, adOpenDynamic, adLockOptimistic, adCmdTable
       rs2.MoveFirst
       rs2.Fields(0).Value = newValue
       rs2.Update
       rs2.Close
       Set rs2 = Nothing
    
       con.Close
       Set con = Nothing
       Exit Function
    
       ErrHandler:
         MsgBox Err.Description
    
       End Function
    
       ' Function to update the changes made to the recordset and
       ' also returns the recordset back to the client.
       Public Function Update(rs As Recordset) As Recordset
       Dim con As New Connection
    
       On Error GoTo ErrHandler
    
       con.Open "dsn=Ram;database=pubs", "sa"
    
       Set rs.ActiveConnection = con
    
       rs.UpdateBatch adAffectAll
    
       Set Update = rs
       Set con = Nothing
       Exit Function
    
       ErrHandler:
        MsgBox "Error in updating ErrDesc: " & Err.Description
        Set Update = rs
        Debug.Print "status at server is " & rs.Status
        Set con = Nothing
    
       End Function
    					
  2. Write a client application (Standard EXE) in VB. In the client application, create the server object, get the disconnected recordset by calling the first method (GetRcdSet) and then modify the first record. Pass the recordset back to the second method of the server (Update) that tries to update the recordset by calling UpdateBatch().

    The STATUS property will be 2050 error (modified and concurrency problem) as expected.

    Now, check the STATUS property of the recordset returned by the Update method of the server. The STATUS property of the returned recordset is 2 (modified) instead of 2050 (modified and concurrency): Sample Code
       Private Sub Command1_Click()
          Dim rs As Recordset
          Dim x As Object
          Dim rs2 As Recordset
    
          Set x = CreateObject("myproj.cls1")
          Set rs = x.GetRcdSet
    
          ' Check the value of Source property.
          ' Source property is empty string here.
          Debug.Print rs.Source
    
          rs.MoveFirst
          ' Modify a field in a recordset.
          rs.Fields(0).Value = "String modified at client"
    
          Set rs2 = x.Update(rs)
    
          Debug.Print "Status at client" & rs2.Status
          Set rs2 = Nothing
         End Sub
    					

Modification Type:MinorLast Reviewed:3/14/2005
Keywords:kbDatabase kbDSupport kbprb KB185423