PRB: Passing a Recordset to a DLL to Do an UpdateBatch More Than Once Causes Error (270636)
The information in this article applies to:
- ActiveX Data Objects (ADO) 2.5
- ActiveX Data Objects (ADO) 2.6
- Microsoft OLE DB Provider for Oracle 2.5
This article was previously published under Q270636 SYMPTOMS
When you call the UpdateBatch method of an ActiveX Data Objects (ADO) Recordset object using the Microsoft OLE DB Provider for Oracle, an error may occur.
With Microsoft Data Access Components (MDAC) version 2.5, the following error message may be returned:
Run-time error '-2147217864 (80040e38)':
Row cannot be located for updating. Some values may have been changed since it was last read.
With MDAC version 2.1, the following error message may be returned:
Run-time error '-2147217864 (80040e38)':
The specified row could not be located for updating: Some values may have been changed since it was last read.
CAUSE
When you have an out-of-process DLL in a 3-tier application, and the DLL is responsible for handling updates to the Oracle server, the following sequence of events may cause this error to occur: - The DLL returns an ADO Recordset to the client.
- The client appends a new record to the Recordset and sends the Recordset back to the DLL.
- The DLL calls UpdateBatch to commit the changes to the Recordset.
- The client modifies the new record and sends the Recordset to the DLL again.
- When the DLL calls UpdateBatch again, the error occurs.
The root problem is that a hidden ROWID column in the Recordset is still set to NULL after the first update on the client-side Recordset. This is because ROWID columns are automatically incremented by the server, and in this case, the client-side Recordset is disconnected; in other words, it has no server connection and therefore cannot be updated automatically. Because this column value is never updated on the client-side, all subsequent updates using this invalid ROWID fail.
RESOLUTION
To prevent this error, set the "Determine Key Columns For Rowset" dynamic property on the Recordset object. The property must be set before the CursorLocation is set to adUseClient. This property is provider-specific, and although it cannot be set once you've asked for a client-side cursor, the property value is retained and used even after the cursor location changes.
Also, in order to ensure that this property is used by the provider, set the ActiveConnection property of your Recordset before setting the "Determine Keys For Rowset" property, and do not pass a connection string into the Open method call for your Recordset.
In the code example in the "More Information" section, the error occurs even though this property is set, because a connection string is passed into the Open call. This forces ADO to create a new Connection object to execute the query, and the property setting is not saved. See the comments within the code for more information on how to prevent this from happening.
Modification Type: | Major | Last Reviewed: | 9/12/2003 |
---|
Keywords: | kbExcel123Quattro kbOracle kbprb kbProvider KB270636 kbAudDeveloper |
---|
|