PRB: Update of Same Record Twice with Disconnect ADO Recordset Fails (193515)
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 Q193515 SYMPTOMS
This article assumes that the reader is familiar with disconnected ActiveX
Data Objects (ADO) recordsets and how to pass these from an out-of-process
server to a client application. For more information on disconnected
recordsets please refer to the article listed in the "References" section.
If the disconnected recordset on the client is updated twice, the changes
made on the second update may not be committed on the server. This is
because the client0side recordset either did not retrieve the updated copy
of the recordset from the server after the first update, or did not call
UpdateBatch on the client recordset to update the OriginalValue properties
of the client-side recordset.
If the disconnected recordset on the client is updated twice without either returning the new updated recordset to the client or without calling UpdateBatch on the client recordset between updates, the second update will not be successful on the server because the client and server data will be out of synch.
RESOLUTION
Use one of the following two examples:
- Return a new updated recordset object to the client after each
UpdateBatch on the server.
-or-
- Perform an UpdateBatch on the client to update the OriginalValue
properties of the recordset to be updated to the values contained in the
Value properties.
STATUSSteps to Reproduce Behavior
There are two main steps to reproduce this behavior. First create an out-of-process server to access the database. Second, create a client to use this
out of process server. The following sample uses the Pubs database that is
provided with SQL Server. You need to alter the connection information in
the code so that it corresponds to your SQL Server.
Create the ActiveX EXE Server- Create a new Visual Basic ActiveX .exe project.
- Create a reference to the Microsoft ActiveX Data Objects Library and also to the Microsoft ActiveX Data Objects Recordset Library.
- From the Project menu, choose Project Properties and rename the project
to ADOTest.
- Paste the following code into the default class module:
Const szConnect = "Driver={SQL Server};Server=yourserver;" & _
"Uid=sa;Pwd=;Database=pubs"
Public Function FLoad() As ADOR.Recordset
Dim rs As ADOR.Recordset
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.CursorLocation = adUseClient
cn.Open szConnect
Set rs = New ADOR.Recordset
Set rs.ActiveConnection = cn
rs.CursorLocation = adUseClient
rs.Open "Select au_lname from authors", cn, _
adOpenKeyset, adLockBatchOptimistic
Set rs.ActiveConnection = Nothing
Set FLoad = rs
End Function
Public Sub Update(ByVal rsClient As ADOR.Recordset)
Dim rsConnection As New ADODB.Connection
Dim rsServer As New ADODB.Recordset
rsConnection.Open szConnect
rsServer.Open rsClient
Set rsServer.ActiveConnection = rsConnection
rsServer.UpdateBatch
End Sub
- From the File menu, choose Make ADOTest.exe.
Create the Client- Create a new Visual Basic Standard .exe project.
- Create a reference to either the Microsoft ActiveX Data Objects Library. Then, create a reference to the ADOTest
component that you just created.
- Add a command button to the default form.
- Add the following code to the default form:
Dim rs As ADOR.Recordset
Set rs = New ADOR.Recordset
Dim obj As ADOTest.Class1
Set obj = New ADOTest.Class1
Set rs = obj.FLoad
'First update.
'---------------------------
rs.MoveLast
rs.MoveFirst
rs(0).Value = "FirstTime"
rs.Update
rs.MarshalOptions = adMarshalModifiedOnly
Debug.Print "OriginalValue after Update (Before method): " _
& rs(0).OriginalValue
obj.Update rs
Debug.Print "OriginalValue after Update:" & rs(0).OriginalValue
'If you comment out the following line the second update
'fails, although it does NOT return an error message. You have
'to look at the data in the table to see that it failed.
'-------------------------------------------------------------
rs.UpdateBatch
Debug.Print "OriginalValue after UpdateBatch:" & rs(0).OriginalValue
'Second update.
'----------------------------
rs.MoveLast
rs.MoveFirst
rs(0).Value = "SecondTime"
rs.Update
rs.MarshalOptions = adMarshalModifiedOnly
obj.Update rs
rs.UpdateBatch
REFERENCES
For additional information about disconnected recordsets, please see the following
article in the Microsoft Knowledge Base:
184397 Getting ADO Disconnected Recordsets in VBA/C++/Java
| Modification Type: | Minor | Last Reviewed: | 3/14/2005 |
|---|
| Keywords: | kbDatabase kbDSupport kbprb KB193515 |
|---|
|