更新のポスト処理のオーバーライド(FireDAC)
データの編集(FireDAC) への移動
目次
FireDAC では、更新 SQL コマンドを自動的に生成できますが、以下のように、場合によっては、それを正しく行えないことがあります。
元の SQL コマンド | 生成された SQL コマンドで起こり得る問題 | 考えられる対策 |
---|---|---|
結合を伴う SELECT | 結合されたテーブルの列が含まれる。 |
|
グループ化の操作を伴う SELECT | 複数のレコードが更新される。 |
|
共通テーブル式を伴う SELECT | 更新対象テーブル名を取得できない。 |
|
エイリアスが設定された列および式を伴う SELECT | 間違った列名が含まれる。 |
|
ストアド プロシージャ呼び出し | 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 エディタ]を起動します。
このエディタでは、関連するデータセットから更新対象テーブル名を自動的に取得し、データセット列 TField.ProviderFlags および TField.AutoGenerateValue に従って列をセットアップします。
セットアップを変更するには、以下を使用します。
- [テーブル名]コンボ ボックス: 更新対象テーブル名を指定します。
- [キー フィールド]リスト ボックス: 一意識別列を指定します(ProviderFlags に
pfInKey
が含まれている場合に相当)。 - [更新対象フィールド]リスト ボックス: 更新対象に含める列を指定します(ProviderFlags に
pfInUpdate
が含まれている場合に相当)。 - [リフレッシュ対象フィールド]リスト ボックス: 更新のポスト後に値をリフレッシュする必要がある列を指定します(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 - 現在のフィールド値を返します。
また、TFDUpdateSQL と OnUpdateRecord の両方のアプローチを組み合わせて、さまざまなテーブルやデータベースに更新を半自動的にポストできるようにすることも可能です。
詳細については、OnUpdateRecord イベントの説明と以下の FireDAC デモを参照してください。
- TFDQuery OnUpdateRecord
- FireDAC\Samples\Comp Layer\TFDUpdateSQL\Main