Delphi.FireDAC. Генерация Update команд

Эта статья о генерации Update команд в FireDAC. Она основана на официальной документации

-Старая версия

-Новая версия

FireDAC по разному обрабатывает следующие команды

Insert / Edit / Post / Delete – моментальное обновление

ApplyUpdates – применяется в режиме “Cached Updates”

Генератор команд FireDAC знает о ключевых полях, запросах, триггерах, специальных типах данных (Oracle BLOB / CLOB / BFILE, и так далее) и генерирует эффективные SQL команды в зависимости от соединения с БД. Это облегчает ручной труд. Также, дополнительно может быть использован компонент TFDUpdateSQL, который позволяет переписать (override) update команды.

Далее приводится пример для базы Oracle, где ключевое поле заполняется триггером, а также есть BLOB поле

FROM, INTO, и UPDATE 

FireDAC использует для обновления главную таблицу во фразе SELECT … FROM …. Также эта таблица будет использована для того, чтобы получить главные ключи mkPrimaryKeyFields. Используйте UpdateOptions.UpdateTableName чтобы явно задать имя обновляемой таблицы. Это требуется когда

-датасет берется из хранимой процедуры TFDStoredProc

TFDQuery содержит не SELECT запрос

-FireDAC неправильно определяет имя главной таблицы

-приложению нужно перенаправить обновления в специальную таблицу

WHERE 

UpdateOptions.UpdateMode контролирует выражение WHERE для отправки обновлений и удалений. Значение по умолчанию upWhereKeyOnly использует во фразе WHERE только уникальные идентификационные колонки unique identifying columns и обеспечивает эффективный и безопасный путь для поиска обновляемой строки. Когда такой колонки нет и невозможно определить обновляемый ряд, FireDAC переключит UpdateOptions.UpdateMode на upWhereAll. Следующие поля, включенные в WHERE могут привести к ошибке “no rows found”

-DOUBLE, FLOAT, TIME, and DATETIME поля и другие поля с плавающей точкой могут привести к потере точности при сравнении величин

-текстовые поля могут иметь неправильную кодировку или лишние пробелы, ведущие к неудачным сравнениям

В таких случаях приложение получает исключение

Если нет уникальных ключей, может выскочить такая ошибка

Решение проблемы может быть следующее

-создавайте корректные уникальные идентификационные колонки

-выключите некоторые поля при использовании WHERE, исключая pfInWhere из соответствующего свойства TField.ProviderFlags

-подавите эти ошибки, устанавливая UpdateOptions.CountUpdatedRecords в False

Учтите, чтобы избежать этих случаев с серверной таблицей SQL, которая также содержит триггеры, создавайте триггеры с инструкцией SET NOCOUNT ON в начале триггера, если это невозможно, тогда устанавливайте UpdateOptions.CountUpdatedRecords в False

SET и VALUES 

Свойство UpdateOptions.UpdateChangedFields управляет полями, которые включаются во фразы  UPDATE SET … or INSERT VALUES …  Установка в TRUE включит только измененные поля, которые помогают

-минимизировать трафик

-обойти некоторые ограничения проверок

-обойти лишние запуски триггеров

-минимизировать генерацию лога

Установка в False, наоборот, включит все поля. Чтобы исключить обновления из колонок – исключите флаг pfInUpdate из соответствующего свойства TField.ProviderFlags.

RETURNING и Additional SELECTs

UpdateOptions.RefreshMode = rmOnDemand управляет автоматическим обновлением значений колонок, которое может быть изменено после вставки или обновления записи. Колонки, которые могут требовать обновления после вставки это

-автоинкрементные колонки

-калькулируемые

-колонки со значениями по умолчанию

-timestamp колонки

-колонки, обновляемые триггером

 

Колонки, которые могут требовать обновления после update инструкций

-калькулируемые

-timestamp

-обновляемые триггером

Кэширование Update команд

Иногда, установка  UpdateChangedFields в False может улучшить производительность. И, скомбинированная с некоторыми другими настройками, такими как свойство UpdateOptions.FastUpdates, позволяет получить лучшую производительность при отправке обновлений, избегая дополнительных запросов и включая кэширование update команд.

Включение FastUpdates = True эквивалентно

 

This entry was posted in Delphi, FireDAC. Bookmark the permalink.