エラーの処理(FireDAC)
接続の操作(FireDAC) への移動
このトピックでは、FireDAC でデータベース エラーを処理する方法を説明します。
概要
EFDDBEngineException クラスがすべての DBMS 例外の基底クラスとなります。単一の例外オブジェクトはデータベース エラーのコレクションで、各エラーは TFDDBError クラスで表され、EFDDBEngineException.Errors[] プロパティを通じてアクセスすることができます。
FireDAC では、EFDDBEngineException 例外クラスおよび TFDDBError エラー クラスの "パーソナル化" と統一化が両立しています。"パーソナル化" とは、以下のように、ドライバが独自の例外クラスとエラー クラスを持つことができ、そこに DBMS 固有の情報が格納されているということです。
TFDDBError には ErrorCode プロパティがあり、DBMS のネイティブ エラー コードを表します。
"統一化" とは、すべてのドライバ例外クラスが、EFDDBEngineException という、ドライバに依存しない情報が格納されている単一の基底クラスから継承されるということです。そのクラスの Kind プロパティは、DBMS に依存しないエラー コードを表します。たとえば、一意キー違反エラーを処理するコードは以下のようなものになります。
try
FDQuery1.ExecSQL('insert into MyTab(code, name) values (:code, :name)', [100, 'Tokyo']);
except
on E: EFDDBEngineException do begin
if E.Kind = ekUKViolated then
ShowMessage('Please enter unique value !');
raise;
end;
end;
エラー情報
エラー情報は主に EFDDBEngineException の以下のプロパティで提供されます。
- Errors -- TFDDBError オブジェクトのコレクション
- ErrorCount -- Errors コレクションに含まれているエラーの数
- Kind -- DBMS に依存しないエラー種別
- Message -- 実際のエラー メッセージ
さらに TFDDBError の以下のプロパティでも提供されます。
アプリケーションのデバッグを簡単にするためや例外のログ記録をもっと有益なものにするため、EFDDBEngineException には SQL プロパティと Params プロパティが用意されています。
さらに、詳細なエラー情報を DBMS で提供できるかどうかやエラーの種類によっては、以下の TFDDBError プロパティも役に立ちます。
- SQL 解析エラーが関係している場合、CommandTextOffset は SQL コマンド テキスト内のオフセットを返します。
- 制約の違反や DB オブジェクト変更の失敗などのエラーが関係している場合、ObjName プロパティはデータベース オブジェクト名を返します。
- 配列 DML のエラーが関係している場合、RowIndex は、そのエラーが属する配列行インデックスを返します。
例外の処理
例外は、以下のいずれかの方法で処理することができます。
- try/except/end 構文要素を使用する。これは、Delphi の標準的な例外処理方法です。以下に例を示します。
FDConnection1.StartsTransaction;
try
FDQuery1.ExecSQL;
FDConnection1.Commit;
except
on E: EFDDBEngineException do begin
FDConnection1.Rollback;
// do something here
raise;
end;
end;
- TFDQuery.OnError イベント ハンドラを設定する。
- TFDConnection.OnError イベント ハンドラを設定する。これらは、例外のログ記録や例外の "調整" を扱う良い方法です。以下に例を示します。
procedure TForm1.FDConnection1Error(ASender: TObject; const AInitiator: IFDStanObject;
var AException: Exception);
var
oExc: EFDDBEngineException;
begin
if AException is EFDDBEngineException then begin
oExc := EFDDBEngineException(AException);
if oExc.Kind = ekRecordLocked then
oExc.Message := 'Please, try the operation later. At moment, the record is busy'
else if (oExc.Kind = ekUKViolated) and SameText(oExc[0].ObjName, 'UniqueKey_Orders') then
oExc.Message := 'Please, provide the unique order information. It seems, your order was already put';
end;
end;
FDConnection1.OnError := FDConnection1Error;
- TFDQuery.OnExecuteError イベント ハンドラを設定する(配列 DML に特有のエラーを処理する場合)。
- TFDQuery.OnUpdateError イベント ハンドラを設定する(更新のポストに関するエラーを処理する場合)。
- TFDConnection.OnLost、OnRestored、OnRecover の各イベント ハンドラを設定する(接続切断エラーを処理する場合)。
エンド ユーザー エラー ダイアログの使用
TFDGUIxErrorDialog コンポーネントを利用すると、エンド ユーザーは、データベースから返されたエラーの通知を受け取ることができます。
このダイアログを使用するには、このコンポーネントをフォームのどこかにドロップするだけです。FireDAC の未処理の例外がある場合、このコンポーネントにより TApplication.OnException イベント ハンドラがフックされ、ダイアログがポップアップされます。ダイアログの[クエリ]ページでは、例外で生成された SQL コマンド テキストを参照できます。ダイアログで Ctrl+C キーを押すと、例外情報がすべてクリップボードにコピーされます。
関連項目
- 接続の回復
- コマンドの実行
- FireDAC.Stan.Error ネームスペース
- TFDCustomConnection.OnError イベント
- TFDAdaptedDataSet.OnError イベント