PRB: Update of Same Record 2x w/Disconnect ADO Recordset FailsID: Q193515 
  | 
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.
This article uses an out of process server to pass an ADO recordset to a
client. The client then makes modifications to the recordset, and passes
the recordset object back to the out-of-process server so that the server
can reconnect to the database and update the data.
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.
ADO recordsets maintain a copy of the original values that were returned
from the database in the OriginalValue property. When the client updates a
disconnected recordset locally, the Value property is modified and the
OriginalValue property is left to reflect the value that was originally in
the database. When the recordset is passed back to the out-of-process
server and an UpdateBatch is performed, a temporary stored procedure is
created and used to update the database values. The OriginalValue property
is used in the WHERE clause when this update is performed. The recordset on
the server side is updated, but because the client still has the original
recordset object the client recordset original values are now out of date.
If the client does not obtain an updated recordset object or perform an
UpdateBatch on the local recordset, the second time the recordset is passed
back to the out-of-process server the OriginalValue property is out of date
and prevents the update from actually taking place.
Use one of the following two examples:
This behavior is by design.
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
  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
 For additional information about disconnected recordsets, please see the following article(s) in the Microsoft Knowledge Base:
Q184397 Getting ADO Disconnected Recordsets in VBA/C++/Java
Additional query words: kbADO150 kbADO200 kbDatabase kbDCOM
Keywords          : kbADO150 kbADO200 kbDatabase 
Version           : WINDOWS:1.5,2.0
Platform          : WINDOWS 
Issue type        : kbprb 
Last Reviewed: May 24, 1999