更新のポスト処理のオーバーライド(FireDAC)

提供: Appmethod Topics
移動先: 案内検索

データの編集(FireDAC) への移動

FireDAC では、更新 SQL コマンドを自動的に生成できますが、以下のように、場合によっては、それを正しく行えないことがあります。

元の SQL コマンド 生成された SQL コマンドで起こり得る問題 考えられる対策
結合を伴う SELECT 結合されたテーブルの列が含まれる。
グループ化の操作を伴う SELECT 複数のレコードが更新される。
共通テーブル式を伴う SELECT 更新対象テーブル名を取得できない。
  • UpdateOptions.UpdateTableName を設定することで、更新を正しいテーブルにリダイレクトします。
  • カスタム SQL コマンドを使用します。
エイリアスが設定された列および式を伴う SELECT 間違った列名が含まれる。
  • 任意で、TField.ProviderFlags から pfInUpdate を除き TField.ReadOnlyTrue に設定することで、更新コマンドから非ベース テーブル列を排除します。
  • 状況に応じて、TField.Origin を指定することでベース列名を指定します。
ストアド プロシージャ呼び出し SELECT に関する上記の問題すべて
カーソル式および変数 SELECT に関する上記の問題すべて
SELECT 以外のその他のコマンド SELECT に関する上記の問題すべて

メモ: 上記が絶対必要というわけではありません。それどころか、実際に何が起こるかをまず確かめてください。

FireDAC では、エイリアスが設定された列または結合された列のベース テーブルとベース列名を検出できます(以下の表を参照)。

DBMS セットアップ
Advantage Database サポートされていません。
Firebird 接続定義パラメータ ExtendedMetadata=True が必要
Informix サポートされていません。
InterBase 接続定義パラメータ ExtendedMetadata=True が必要
IBM DB2 自動
MS Access 自動
MS SQL Server 接続定義パラメータ ExtendedMetadata=True が必要
MySQL 自動
Oracle サポートされていません。
PostgreSQL 接続定義パラメータ ExtendedMetadata=True が必要
SQL Anywhere 自動
SQLite 自動
Teradata Database 接続定義パラメータ ExtendedMetadata=True が必要

更新テーブル名の指定

場合によっては、アプリケーションで代わりの DB テーブル名を指定して、そこに更新がポストされるようにする必要があります。それには、UpdateOptions.UpdateTableName を、必要なテーブル名に設定します。

更新列の名前とモードの指定

場合によっては、アプリケーションで更新 SQL コマンドから列を除く必要があります。それには、TField.ProviderFlags から pfInUpdate を除きます。さらに、TField.ReadOnly を設定すると、フィールド値の変更を禁止できます。

代わりの DB 列名を指定するには、TField.Origin を、必要な値に設定します。

TFDUpdateSQL の使用

TFDUpdateSQL コンポーネントを使用すると、以下が可能です。

  • FireDAC で生成された更新 SQL コマンドを選択的にオーバーライドすること。
  • 複雑な SELECT 文やストアド プロシージャ呼び出しなど、FireDAC で更新コマンドを生成できない場合に、更新をポストできるようにすること。

一般に、TFDUpdateSQL は更新 SQL コマンドのコレクションで、その各コマンドでは、データベースへの新規レコードの挿入のような特定のタスクを処理します。TFDUpdateSQL は、設計時または実行時あるいはその両方でセットアップすることができます。

設計時でのセットアップ

設計時にセットアップするには、TFDUpdateSQL をフォームにドロップします。データセットの UpdateObject プロパティがこのコンポーネントを指すように設定します。その後、TFDUpdateSQL をダブルクリックして[FireDAC 更新 SQL エディタ]を起動します。

FDUpdateSQLEditor.png

このエディタでは、関連するデータセットから更新対象テーブル名を自動的に取得し、データセット列 TField.ProviderFlags および TField.AutoGenerateValue に従って列をセットアップします。

セットアップを変更するには、以下を使用します。

  • [テーブル名]コンボ ボックス: 更新対象テーブル名を指定します。
  • [キー フィールド]リスト ボックス: 一意識別列を指定します(ProviderFlagspfInKey が含まれている場合に相当)。
  • [更新対象フィールド]リスト ボックス: 更新対象に含める列を指定します(ProviderFlagspfInUpdate が含まれている場合に相当)。
  • [リフレッシュ対象フィールド]リスト ボックス: 更新のポスト後に値をリフレッシュする必要がある列を指定します(AutoGenerateValue <> arNone に相当)。

[DB に従って記述]ボタンを使用すると、メタデータをデータベースから取得することで、指定したテーブルをセットアップできます。[デフォルトに戻す]ボタンを使用すると、データセット フィールド プロパティを使ってセットアップできます。追加オプションについては、[オプション]ページで指定することができます。

セットアップの完了後、[SQL を生成]ボタンをクリックすると、更新 SQL コマンド一式を生成できます。また、このエディタの[SQL コマンド]ページで更新 SQL コマンドを手動で編集することもできます。

[OK]をクリックすると、変更内容が TFDUpdateSQL に保存されます。

実行時でのセットアップ

TFDUpdateSQL の SQL コマンドを実行時に指定するには、アプリケーションで XxxxSQL プロパティを使用しなければなりません。SQL で特定の列値への参照を使用するには、以下のパラメータ マーカーを使用します。

  • 新しい列値 - :NEW_<列名>;
  • 古い列値 - :OLD_<列名>;
  • 現在の列値 - :<列名>.

これらのパラメータ値は FireDAC により自動的に割り当てられます。これらに値を割り当てないでください。値がオーバーライドされるからです。FireDAC では、上記以外の名前のパラメータは無視します。

コマンド パラメータとコマンド マクロは、実行時にのみセットアップすることができます。それを行うには、TFDUpdateSQL.Commands プロパティを使用する必要があります。これは TFDCommand オブジェクトへの参照を返します。以下に例を示します。

FDUpdateSQL1.InsertSQL.Text := 'insert into &tab (id, name) values (:new_id, :new_name)';
FDUpdateSQL1.Commands[arInsert].Macros[0].AsRaw := 'Orders';

OnUpdateRecord の使用

このイベントを使用すると、データセットからの更新のポストを完全にオーバーライドできます。イベント ハンドラ コードでは、以下のデータセット フィールド プロパティを読み取ることができます。

  • OldValue - 元のフィールド値(取得時または直近の CommitUpdates/CancelUpdates 呼び出し後の値)を返します。
  • CurValue / Value - 現在のフィールド値を返します。

また、TFDUpdateSQLOnUpdateRecord の両方のアプローチを組み合わせて、さまざまなテーブルやデータベースに更新を半自動的にポストできるようにすることも可能です。

詳細については、OnUpdateRecord イベントの説明と以下の FireDAC デモを参照してください。

  • FireDAC\Samples\Comp Layer\TFDQuery\CachedUpdates\OnUpdateRecord
  • FireDAC\Samples\Comp Layer\TFDUpdateSQL\Main

関連項目