BUG: Access ODBC Keyset Cursor Becomes Corrupt After a Delete

ID: Q230131

The information in this article applies to:


After deleting a row and doing a MoveNext or MovePrevious, the current record is wrong.

Exhibited behavior indicates that the current record will either become another record from within the recordset or EOF depending on the size of the recordset.


A bug was introduced in MDAC 2.1 affecting the behavior of the Access ODBC Driver keyset cursors.


A supported fix that corrects this problem is now available from Microsoft, but it has not been fully regression tested and should be applied only to systems experiencing this specific problem.

Contacting Microsoft Product Support Services is not necessary unless you are having trouble installing or using this fix. This hotfix has been posted to the following Internet location as JetODBC.exe:



Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.


The specific MDAC 2.1 DLL causing the problem is odbcjt32.dll.

Version 4.0.3513.00 shipped with MDAC 2.1 that was included with SQL Server 7.0.

Version 4.0.3711.08 of odbcjt32.dll shipped with MDAC 2.1 SP1.

MDAC 2.1 SP1 has shipped with Office 2000 and is downloadable at the MDAC Web site:


Included in the hotfix download are both the Jet ODBC driver files and the Jet ISAM driver files. The Jet ODBC files are odbcjt32.dll and odbcji32.dll, the ISAM driver files are odexl32.dll, odfox32.dll, odpdx32.dll and odtext.dll.

Manual Installation

  1. Close all applications or services that are known or suspected to be using Odbcjt32.dll.

  2. Download the hotfix into a temporary directory and unzip it.

  3. Locate the current Jet ODBC files and rename them. These should exist in the \winnt\system32 folder or the \windows\system folder.

  4. Copy the hotfix Jet ODBC files into the same location.

Important Notice for Win9x Users!

If you are installing this fix onto a Windows 95 machine, or a machine with theoriginal release of Windows 98, you will need to install the Windows 98 Migration DLL included with this fix. This Migration DLL is only required underWindows 95 or Windoes 98 OSRx systems being upgraded to Win9 OSR(x+1).

This Migration DLL is not needed for Win9x systems upgrading to Windows 2000, nor isit needed for any Windows NT 4.0 or Windows 2000 system. The Windows 98 Migration DLL ensures that subsequent updates to Windows 98 will not overwrite this fix with older versions of the same files. Without the Migration DLL, Windows 98 OSR2 (for example) will install MDAC 2.1 SP1a (the G.A. release), overwriting the fix described in this article which is newer than MDAC 2.1 SP1a.

Listed below are the files needed to install the Windows 98 Migration DLL for this release:

Follow these steps to correctly install the Windows 98 Migration DLL for MDAC 2.1 SP1a:
  1. Copy MDACMIGR.DLL to the Windows directory where Windows 9x is installed

  2. Invoke the migrate.reg file to register MDACMIGR.DLL.

Because key parts of Windows 98 setup technology are written in Win16, the Windows 98 Migration DLL is written using the Win16 API and, therefore, does not self-register. This Migration DLL is written specifically for Windows 98 OSR2 and will work to preserve any fix written against MDAC 2.1 SP1a.

The following Visual C++ code in conjunction with the Microsoft sample Northwind database can be used to illustrate the behavior. It assumes that you used the MFC AppWizard to generate a CRecordset-derived class that wraps the Order Details table in nwind.mdb. The recordset must be opened as a CRecordset::dynaset to reproduce the problem:

   CDBwindSet rs;

   rs.MoveNext();  //You are now on the wrong record
The following Visual Basic code in conjunction with the Microsoft sample Northwind database can be used to illustrate the behavior. The cursor type needs to be adOpenDynamic. ADO will degrade to a keyset cursor because the Access ODBC driver does not support dynamic cursors.

It appears that setting the ADO recordset property CacheSize to something other than 1 (the default) causes the bug to not appear:

   Dim cnNorthwind As ADODB.Connection 
   Dim rsOrderDetails As ADODB.Recordset

   Private Sub Form_Load()
       Dim strConn As String
       Dim strSQL As String
       strConn = "Provider=MSDASQL;Driver={Microsoft Access Driver (*.mdb)};DBQ=c:\temp\NWind.MDB;"
       strSQL = "SELECT * FROM [Order Details] ORDER BY OrderID, ProductID"
       Set cnNorthwind = New ADODB.Connection
       cnNorthwind.Open strConn
       Set rsOrderDetails = New ADODB.Recordset
       rsOrderDetails.Open strSQL, cnNorthwind, adOpenDynamic, adLockOptimistic, adCmdText<BR/>
       MsgBox "Row 2 = " & rsOrderDetails!OrderID & " - " & rsOrderDetails!ProductID

       'Note you expect to be on Row 2 as before but you are not
       MsgBox "Row 2 = " & rsOrderDetails!OrderID & " - " & rsOrderDetails!ProductID
   End Sub 

Additional query words:

Keywords          : kbADO210bug kbJET kbGrpVCDB 
Version           : WINDOWS:2.1,2.1 SP1
Platform          : WINDOWS 
Issue type        : kbbug 

Last Reviewed: July 27, 1999