Microsoft KB Archive/185423

= PRB: Most ADO Recordset Properties Are Not Marshalled =

Article ID: 185423

Article Last Modified on 3/14/2005

-

APPLIES TO


 * Microsoft ActiveX Data Objects 1.5
 * Microsoft ActiveX Data Objects 2.0
 * Microsoft ActiveX Data Objects 2.1 Service Pack 2
 * Microsoft ActiveX Data Objects 2.5
 * Microsoft ActiveX Data Objects 2.6
 * Microsoft ActiveX Data Objects 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.



Steps to Reproduce Behavior
  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   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 

Keywords: kbdatabase kbprb KB185423

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.