fibplus
fibplus copied to clipboard
TpFIBQuery. закрытие транзакции после первого фетча
если у TpFIBQuery задать следующие параметры
GoToFirstRecordOnExecute = True;
qoStartTransaction = true
qoAutoCommit = true
то при выборке select
происходит закрытие транзакции после первого фетча, что приводит к ошибке выполнения
смотрим код в версия 7.6 код
if FGoToFirstRecordOnExecute
then begin
DoAfterExecute(Assigned(FMDTMainDataOrder), vAfterExecEvent);
vAfterExecEvent := False;
Next;
end;
в версии 7.5 код был такой
if FGoToFirstRecordOnExecute then
Next;
думаю DoAfterExecute
лишний в версии 7.6 этот код выполнится позже
Да, там проблема, при select стэйтментов он все равно делает commit в DoAfterExecute. Позже этот код не выполняется так как ставится флаг vAfterExecEvent. Буду переделывать как у датасетов: Если select то не сделать Commit. Наверное это лучший компроммис когда AutoCommit.
я правильно понимаю, что тут может помочь пока только использование FetchAll ?
FetchAll нет в FIBQuery. для себя закомментировал
if FGoToFirstRecordOnExecute
then begin
// DoAfterExecute(Assigned(FMDTMainDataOrder), vAfterExecEvent);
// vAfterExecEvent := False;
Next;
end;
точно. посмотрел. это в Dataset реализовано как Bookmark + Last
Данный фикс "сломал" функционал получения количества записей, который был раньше работал корректно и вполне логично: В событии OnAfterExecute проверяется количество записей через свойство RecordCount. Соответственно перенос кода
if FGoToFirstRecordOnExecute and FOpen then
Next;
после вызова события DoAfterExecute не логично и "ломает" работу компонента.
- При проверке количества записей в событии DoAfterExecute соответственно получаем 0.
- Выбор следующей записи вполне логично для SQLSelect, а не для всех типов SQL.
- DoAfterExecute как следует из названия должен выполнялся самой последней инструкцией, после всех действий.
Лучше явно управлять транзакциями, чем пытаясь вылечить "автоматический" режим "сломать" основной функционал.
Привет, AnryJester, Да, щас проблема в том что DoAfterExecute вызывается до Next и собственно получается RecordCount = 0. Хотя незнаю если правильнее так как было. Будем править, чтобы не ломать совместимость.
Anry, смотрел код.
В 7.6 DoAfterExecute и выполняется до Next, независимо от этого фикса. этого было до. В 7.5 было иначе да, сначала Next а потом DoAfterExecute. Я нахожу логику в 7.6 более правильной. В DoAfterExecute RecordCound максимум может быть 1, после одного фетча что позволяет проверять только если есть записи и ничего другое. Посмотрим что скажет сообщество. Можно фиксить только ради совместимости.
- Выбор следующей записи вполне логично для SQLSelect, а не для всех типов SQL.
Еще для сингулярных запросов тоже, типа execute procedure. Хотя в FB3 уже это не работает. Уже курсор с одной записи не открывается.
- DoAfterExecute как следует из названия должен выполнялся самой последней инструкцией, после всех действий.
Next уже как бы не связан с Execute. есть isc_execute а есть isc_fetch.
Я бы вообще описал RecordCount как deprecated По идее, нужно бы пользоваться явным RecordCountFromSrv