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.
MORE INFORMATION
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 CodePrivate 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