Этот код:
FDConnection.Open; // Design time TFDConnection; default settings
TabelGrid.Close; // TDFTable connected to TFDConnection; default settings
TabelGrid.TableName := 'TT_ACT';
TabelGrid.Open;
TabelGrid.Edit;
TabelGrid.FieldByName('TT_NAME').AsString := TabelGrid.FieldByName('TT_NAME').AsString + '*';
TabelGrid.Post;
терпит неудачу с
[FireDAC][Phys][IB]-312 Exact update affected [0] rows, while [1] was requested
, если установлен Firebird 2.5.7, не , если установлен Firebird 2.5.3.
Стек вызовов:
Условия:
-
TFDConnection
указывает на локальный файл .GDB, ID драйвера IB или FB, пароль по умолчанию sysdba
, все настройки по умолчанию. TFDPhysIBDriverLink
или TFDPhysFBDriverLink
присутствует.
- Delphi Tokyo 10.2.3 Код Win32, Windows 7
- Firebird установлен с возможностью поставить gds32.dll в System32; нет ложные библиотеки Firebird, лежащие вокруг
- Interbase отсутствует в системе
Таблица имеет 3 индекса:
TT_I0_ACT TT_ACT_ID Primary
TT_I1_ACT TT_PARENT_ID
TT_I2_ACT TT_FROMDATE
Я возился с настройками, особенно изменил значения по умолчанию UpdateOptions.UpdateMode
s с UpWhereKeyOnly
на UpWhereChanged
или UpWhereAll
, но пока никаких результатов.
Что может происходить; что еще я могу расследовать?
Мы распространяем Firebird 2.5.3 с нашим приложением, но я боюсь, что оно потерпит неудачу, когда у клиентов уже будет более поздняя версия (как мы узнали, когда один из наших разработчиков обновил FB).
Дополнительные исследования:
Запрос, который я вижу в TFDPhysCommandAsyncExecute.Execute
(FireDAC.Phys.pas
) для обеих версий, (с режимом обновления UpWhereKey
по умолчанию):
UPDATE TT_ACT SET TT_NAME = :NEW_TT_NAME WHERE RDB$DB_KEY = :OLD_DB_KEY
(на самом деле все свойства FCommand
в инспекторе отображаются одинаково).
Я просматривал Firebird 2.5.x. заметки о выпуске и видел только один в 2.5.6, который несколько связан:
Количество затронутых строк было сообщено неверно для обновления для представления, созданного с опцией CHECK
Я не уверен, что это применимо, потому что это о взглядах. Установка для UpdateOptions.CountUpdatedOptions
значения false не имеет значения.
В списке исправлений 2.5.8 нет ничего, что указывало бы на наличие соответствующей ошибки в версиях 2.5.4-2.5.7.
Я проследил код FireDAC до точки, где выполнение отличается в 2.5.3 и 2.5.7, но это заканчивается интерфейсным методом, который я не могу отследить:
TFDTable.InternalPost
TFDDataSet.InternalPost
TFDAdaptedDataSet.DoProcessUpdateRequest(arUpdate
TFDCustomTableAdapter.Update
TFDCustomTableAdapter.UpdateAdapterCmds(const ACmds: array of TFDActionRequest);
ACmds contains (arUpdate, arFetchRow)
back to TFDCustomTableAdapter.Update
TFDDAptTableAdapter.Update
TFDDAptTableAdapter.ProcessUpdate
In the 'build command if required' part
oCmd.SQLText := 'UPDATE TT_ACT'#$A'SET TT_NAME = ?'#$A'WHERE RDB$DB_KEY = ?'
ProcessRequest
in TFDDAptTableAdapter.ProcessRequest
SetParamsFromRow(ACommand.Params, ARow);
AParams.Count=2: NEW_TT_NAME and OLD_DB_KEY. OLD_DB_KEY value is 0 in both cases
then
ACommand.Execute;
TFDPhysCommand.Execute
ExecuteTask
TFDPhysCommand.ExecuteTask
FExecutor.Run
TFDStanAsyncExecutor.Run;
TFDStanAsyncExecutor.ExecuteOperation
FOperationIntf.Execute;
TFDPhysCommandAsyncExecute.Execute
TFDPhysCommand.ExecuteBase
FExecutor.Launched; -> Interface, cannot trace
Process_SingleRow
Process_HandleSystemFailure
InternalExecute -> Interface, cannot trace
Этот последний вызов возвращается с параметром var ACount, равным 1 для 2.5.3 и 0 для 2.5.7
Функция GetRowCounts возвращает
FRowsUpdated,FRowsDeleted,FRowsSelected,FRowsInserted: 1 0 1 0 in 2.5.3
FRowsUpdated,FRowsDeleted,FRowsSelected,FRowsInserted: 0 0 0 0 in 2.5.7