Сбой редактирования TFDTable в Firebird 2.5.7, а не 2.5.3 - PullRequest
0 голосов
/ 04 июля 2018

Этот код:

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.

Стек вызовов:

enter image description here

Условия:

  • 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
...