OnUpdateRecord イベント ハンドラの作成
BDE を使用した更新情報のキャッシュ:インデックス への移動
メモ: ボーランド データベース エンジン(BDE)は推奨されなくなったので、今後は機能強化されません。たとえば、BDE では Unicode はサポートされません。BDE を使用して新規に開発を始めないでください。既存のデータベース アプリケーションを BDE から dbExpress に移行することを検討してください。
BDE 対応データセットがそのキャッシュアップデートを適用するときは、キャッシュ内のすべての変更レコードを、基になったテーブル内の対応するレコードに適用する試みが繰り返して行われます。変更、削除、または新規挿入された各レコードについて更新が適用されようとするとき、データセットコンポーネントの OnUpdateRecord イベントが発生します。
OnUpdateRecord イベントにハンドラを定義すると、現在のレコードの更新が実際に適用される直前にアクションを実行できます。そのようなアクションとして、データの検証、ほかのテーブルの更新、特殊パラメータの置換、複数のアップデートオブジェクトの実行などがあります。OnUpdateRecord イベントのハンドラによって、更新プロセスの制御性が高まります。
OnUpdateRecord イベントハンドラの概略コードを次に示します。
procedure TForm1.DataSetUpdateRecord(DataSet: TDataSet; UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction); begin { ここで更新を実行... } end;
void __fastcall TForm1::DataSetUpdateRecord(TDataSet *DataSet, TUpdateKind UpdateKind, TUpdateAction &UpdateAction) { // ここで更新を実行... }
DataSet パラメータは更新のあるキャッシュされたデータセットを指定します。
UpdateKind パラメータは、現在のレコードに対して実行する必要がある更新の種類を表します。UpdateKind の値は、ukModify、ukInsert、または ukDelete です。アップデートオブジェクトを使用する場合は、更新を適用するときにこのパラメータをアップデートオブジェクトに渡す必要があります。更新の種類に基づいてハンドラが何か特殊な処理を実行する場合は、このパラメータを調べる必要もあります。
UpdateAction パラメータは、更新を適用したかどうかを示します。UpdateAction の値は、uaFail(デフォルト)、uaAbort、uaSkip、uaRetry、または uaApplied です。イベントハンドラが更新の適用に成功した場合は、終了前にこのパラメータを uaApplied に変更します。現在のレコードを更新しないことに決めた場合は、値を uaSkip に変更して未適用の変更をキャッシュに保持します。UpdateAction の値を変更しない場合、そのデータセットの更新操作全体が中止され、例外が発生します。UpdateAction を uaAbort に設定すると、エラーメッセージを発生させないように指定できます(サイレント例外)。
これらのパラメータに加えて、現在のレコードに関連付けられた項目コンポーネントの OldValue プロパティや NewValue プロパティを使用できます。OldValue は、データベースから取得した元の項目値です。このプロパティは、更新するデータベースレコードを検索する場合に使用します。NewValue は、適用しようとしている更新内容に含まれている編集済みの値です。
警告: OnUpdateError イベントハンドラや OnCalcFields イベントハンドラと同様に、OnUpdateRecord イベントハンドラは、データセット内の現在のレコードを変更するようなメソッドを決して呼び出してはなりません。
次の例は、このハンドラのパラメータとプロパティの使い方を示しています。この例では、TTable コンポーネントの UpdateTable を使って更新を適用します。実際には更新オブジェクトを使用する方が簡単ですが、テーブルを使用することで動作を詳しく説明しています。
procedure TForm1.EmpAuditUpdateRecord(DataSet: TDataSet; UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction); begin if UpdateKind = ukInsert then UpdateTable.AppendRecord([DataSet.Fields[0].NewValue, DataSet.Fields[1].NewValue]) else if UpdateTable.Locate('KeyField', VarToStr(DataSet.Fields[1].OldValue), []) then case UpdateKind of ukModify: begin UpdateTable.Edit; UpdateTable.Fields[1].AsString := VarToStr(DataSet.Fields[1].NewValue); UpdateTable.Post; end; ukInsert: begin UpdateTable.Insert; UpdateTable.Fields[1].AsString := VarToStr(DataSet.Fields[1].NewValue); UpdateTable.Post; end; ukDelete: UpdateTable.Delete; end; UpdateAction := uaApplied; end;
void __fastcall TForm1::EmpAuditUpdateRecord(TDataSet *DataSet, TUpdateKind UpdateKind, TUpdateAction &UpdateAction) { if (UpdateKind == ukInsert) { TVarRec values[2]; for (int i = 0; i < 2; i++) values[i] = DataSet->Fields->Fields[i]->NewValue; UpdateTable->AppendRecord(values, 1); } else { TLocateOptions lo; lo.Clear(); if (UpdateTable->Locate("KeyField", DataSet->Fields->Fields[0]->OldValue, lo)) switch (UpdateKind) { case ukModify: UpdateTable->Edit(); UpdateTable->Fields->Fields[1]->Value = DataSet->Fields->Fields[1]->Value; UpdateTable->Post(); break; case ukDelete: UpdateTable->Delete(); break; } } UpdateAction = uaApplied; }