Я получаю это исключение:
EOleException: либо BOF, либо EOF имеет значение True, либо текущая запись была удалена. Для запрошенной операции требуется текущая запись
пытаюсь удалить запись:
if SetupTable.Locate('MyFieldName', AKey, []) then
SetupTable.Delete
Здесь происходит проверка наличия записи в базе данных, и если да, то она удаляется. Моя проблема в том, что запись существует, но ее удаление приводит к указанному выше исключению.
Это настройка для одного пользователя, и запись не может исчезнуть между выполнением этих двух строк.
Этот код работает нормально уже 8 лет. Исключение возникает только в Windows 8. Я видел его на 5 разных сайтах клиентов. Клиенты, использующие Windows XP, Vista, 7, не видят проблемы.
Я использую Delphi XE для доступа к базе данных MS Access через ADO с провайдером Microsoft.Jet.OLEDB.4.0.
вот дамп стека:
0073f59d DSALon.exe ADODB 4712 DoRecordsetDelete
0073f5b6 DSALon.exe ADODB 4719 TCustomADODataSet.InternalDelete
006b3dd1 DSALon.exe DB 12947 TDataSet.CheckOperation
006b3ad8 DSALon.exe DB 12856 TDataSet.Delete
007cade6 DSALon.exe DatabaseUnit 629 ClearSetup
Оскорбительный фрагмент кода в ADODB выглядит следующим образом:
procedure DoRecordsetDelete(DataSet: TCustomADODataSet; AffectRecords: TAffectRecords);
begin
with DataSet do
try
Recordset.Delete(AffectRecordsValues[AffectRecords]);
{ When CacheSize > 1, Recordset allows fetching of deleted records.
Calling MovePrevious seems to work around it }
if (CacheSize > 1) and (PRecInfo(ActiveBuffer).RecordNumber <> 1) then
begin
Recordset.MovePrevious;
Recordset.MoveNext;
end;
Recordset.MoveNext;
except
on E: Exception do
begin
Recordset.CancelUpdate;
DatabaseError(E.Message);
end;
end;
end;
что наводит меня на мысль, что здесь важен CacheSize. Я использую CacheSize > 1.
Справка MSDN по свойству ADO CacheSize говорит:
Если для параметра CacheSize задано значение больше единицы, методы навигации (Move, MoveFirst, MoveLast, MoveNext и MovePrevious) могут привести к переходу к удаленной записи, если удаление происходит после извлечения записей. После первоначальной выборки последующие удаления не будут отражаться в кэше данных до тех пор, пока вы не попытаетесь получить доступ к значению данных из удаленной строки. Однако установка значения CacheSize, равного единице, устраняет эту проблему, поскольку удаленные строки не могут быть извлечены.
Тем не менее, я на 100% уверен, что запись, которую я пытаюсь удалить, еще не удалена.
Но, возможно, повторная синхронизация перед поиском поможет избежать проблемы.