Индекс был вне диапазона на ADOQuery - очень случайно
Я получаю Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
случайно по электронной почте мне на моем сайте. Я не могу воспроизвести эту ошибку ни с помощью силы, ни с помощью общего тестирования, и это несколько сбивает с толку.
Из того, что я вижу в трассировке стека, это происходит случайным образом при открытии набора данных и попытке получить значение. Трассировка стека показала, что я получил ошибку при вызове этой функции:
function TDB.FGetLastInsertID: Integer;
const
selSQL = 'select scope_identity() as LastID';
var
selCursor: TDataSet;
begin
selCursor := Cursor(selSQL); //Returns a DataSet from a TADOQuery
try
Result := selCursor.FieldByName('LASTID').AsInteger;
finally
selCursor.Close;
selCursor.Free;
end;
end;
Как я уже сказал, я не могу заставить это воспроизвести ошибку, и, похоже, это происходит случайно при любом запросе, который я запускаю. Я попытался закрыть соединение, установить его в неактивное состояние, чтобы воспроизвести ошибку, но не могу.
У кого-нибудь есть идеи?
РЕДАКТИРОВАТЬ: Кажется, это вызывает проблемы после более тщательного изучения трассировки стека:
Stack Trace: at
System.Collections.ArrayList.get_Item(Int32 index) at
Borland.Vcl.TList.Delete(Int32 Index) at Borland.Vcl.TList.Remove(Object Item) at
Borland.Vcl.TDBBufferList.FreeHGlobal(IntPtr Ptr) at
Borland.Vcl.TCustomADODataSet.FreeRecordBuffer(IntPtr& Buffer) at
Borland.Vcl.TDataSet.SetBufListSize(Int32 Value) at
Borland.Vcl.TDataSet.CloseCursor() at
Borland.Vcl.TDataSet.SetActive(Boolean Value) at Borland.Vcl.TDataSet.Close()
EDIT2: я поставил проверку в коде, чтобы убедиться, selCursor.Active
перед selCursor.Close. Трассировка стека предполагает, что закрывать нечего.
3 ответа
Очень странно, и я до сих пор не знаю, почему, но кажется, что случайно Курсор уже закрыт. Кажется, что добавление:
if (selCursor.Active) then
selCursor.Close;
разобрал проблему...
Спасибо за ответы и потраченное время, пытаясь помочь.
Что произойдет, если курсор вернет пустой набор данных?
Вы пытаетесь получить доступ к selCursor.FieldByName ...
без записи, я думаю.
selCursor := Cursor(selSQL); //Returns a DataSet from a TADOQuery
Возможно проблема здесь, FieldByName в обработчике исключений, поэтому у вас есть ошибка на следующей строке. Вы должны проверить, в порядке ли Cursor().