キャッシュ アップデート エラーの処理
BDE を使用した更新情報のキャッシュ:インデックス への移動
メモ: ボーランド データベース エンジン(BDE)は推奨されなくなったので、今後は機能強化されません。たとえば、BDE では Unicode はサポートされません。BDE を使用して新規に開発を始めないでください。既存のデータベース アプリケーションを BDE から dbExpress に移行することを検討してください。
Borland Database Engine(BDE)は、更新を適用しようとするとき、特にユーザーによる更新の競合がないかやその他の条件をチェックし、エラーがあれば報告します。データセットコンポーネントの DBTables.OnUpdateError イベントを使用すると、エラーを検出してエラーに応答できます。キャッシュアップデートを使用する場合は、このイベントのためのハンドラを作成してください。作成しない場合にエラーが発生すると、更新操作全体が失敗に終わります。
OnUpdateError イベントハンドラの概略コードを次に示します。
procedure TForm1.DataSetUpdateError(DataSet: TDataSet; E: EDatabaseError; UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction); begin { ... ここで更新エラー処理を実行 ... } end;
void __fastcall TForm1::DataSetUpdateError(TDataSet *DataSet, EDatabaseError *E, TUpdateKind UpdateKind, TUpdateAction &UpdateAction) { // ここでエラーに応答... }
DataSet は更新が適用されるデータセットを参照します。エラーの処理時には、このデータセットを使って新しい値と古い値にアクセスできます。各レコード内の項目の元の値は、読み出し専用の TField プロパティ OldValue に格納されます。変更された値は TField プロパティの NewValue に格納されます。イベントハンドラで更新値を調査したり変更するためには、これらの値を利用する方法しかありません。
警告: 現在のレコードを変更するデータセットメソッド(Next や Prior など)は呼び出さないでください。呼び出すと、イベントハンドラが無限ループに入ります。
E パラメータは通常 EDBEngineError 型です。この例外の型からは、ユーザーに表示できるエラーメッセージをエラーハンドラで抽出できます。たとえば次のコードは、ダイアログボックスのキャプションにエラーメッセージを表示するのに使用できます。
ErrorLabel.Caption := E.Message;
ErrorLabel->Caption = E->Message;
このパラメータは、更新エラーの実際の原因を調査する場合にも役立ちます。EDBEngineError から特定のエラーコードを抽出し、それに基づいて適切な処理を実行できます。
UpdateKind パラメータは、エラーを生成した更新の種類を示します。実行中の更新の種類に基づいてエラーハンドラで特別な処理を実行するのでなければ、コードでこのパラメータは使用しません。
UpdateKind の値の一覧を次の表に示します。
UpdateKind の値 :
値 | 意味 |
---|---|
ukModify |
既存のレコードの編集でエラーになった |
ukInsert |
新規レコードの挿入でエラーになった |
ukDelete |
既存のレコードの削除でエラーになった |
UpdateAction
は、イベントハンドラが終了した後で進める更新処理の内容を BDE に指示します。更新エラーハンドラが初めて呼び出されたときに、このパラメータの値は必ず uaFail に設定されます。エラーを引き起こしたレコードのエラー条件とその修正のための措置に基づき、通常はハンドラの終了前に UpdateAction
を別の値に設定します。
- エラーハンドラの呼び出しの原因となったエラー条件をエラーハンドラで修正できる場合は、
UpdateAction
を終了時にとる適切な操作に設定します。エラー条件を修正できた場合は、UpdateAction
を uaRetry に設定してそのレコードの更新を再度適用します。 - uaSkip に設定すると、エラーを引き起こした行の更新はスキップされ、そのレコードの更新はほかのすべての更新が完了した後もキャッシュ内に残ります。
- uaFail と uaAbort はどちらも更新操作全体を終了します。uaFail は例外を生成し、エラーメッセージを表示します。uaAbort はサイレント例外を生成します(エラーメッセージを表示しない)。
次のコードに示す OnUpdateError イベントハンドラは、更新エラーがキー違反に関係するかどうかを調査し、関係する場合には UpdateAction
パラメータを uaSkip に設定します。
{ この例では Bde を uses 節に追加する } if (E is EDBEngineError) then with EDBEngineError(E) do begin if Errors[ErrorCount - 1].ErrorCode = DBIERR_KEYVIOL then UpdateAction := uaSkip { キー違反の場合、このレコードをスキップする } else UpdateAction := uaAbort; { 原因不明の場合、更新を中止する } end;
// この例のユニットファイルにある BDE.hpp をインクルード void __fastcall TForm1::DataSetUpdateError(TDataSet *DataSet, EDatabaseError *E, TUpdateKind UpdateKind, TUpdateAction &UpdateAction) { UpdateAction = uaFail; // 初期化して更新を終了させる if (E->ClassNameIs("EDBEngineError")) { EDBEngineError *pDBE = (EDBEngineError *)E; if (pDBE->Errors[pDBE->ErrorCount - 1]->ErrorCode == DBIERR_KEYVIOL) UpdateAction = uaSkip; // キー違反の場合、このレコードをスキップする } }
メモ: キャッシュアップデートの適用中にエラーが発生すると、例外が生成されてエラーメッセージが表示されます。ApplyUpdates が try...except 構造内で呼び出されなければ、OnUpdateError イベントハンドラ内からユーザーにエラーメッセージが表示され、アプリケーションで同じメッセージが二度表示される恐れがあります。エラーメッセージの繰り返しを防止するには、
UpdateAction
を uaAbort に設定して、システムによって生成されるエラーメッセージの表示をオフにします。