エラーの処理(FireDAC)

提供: RAD Studio
移動先: 案内検索

接続の操作(FireDAC) への移動


このトピックでは、FireDAC でデータベース エラーを処理する方法を説明します。

概要

EFDDBEngineException クラスがすべての DBMS 例外の基底クラスとなります。単一の例外オブジェクトはデータベース エラーのコレクションで、各エラーは TFDDBError クラスで表され、EFDDBEngineException.Errors[] プロパティを通じてアクセスすることができます。

FireDAC では、EFDDBEngineException 例外クラスおよび TFDDBError エラー クラスの "パーソナル化" と統一化が両立しています。"パーソナル化" とは、以下のように、ドライバが独自の例外クラスとエラー クラスを持つことができ、そこに DBMS 固有の情報が格納されているということです。

DBMS 例外クラス エラー クラス
Advantage Database FireDAC.Phys.ADSWrapper.EADSNativeException FireDAC.Stan.Error.TFDDBError
DataSnap サーバー FireDAC.Phys.TDBXBase.ETDBXNativeException FireDAC.Stan.Error.TFDDBError
dbExpress v4 FireDAC.Phys.TDBXBase.ETDBXNativeException FireDAC.Stan.Error.TFDDBError
Firebird FireDAC.Phys.IBWrapper.EIBNativeException FireDAC.Phys.IBWrapper.TFDIBError
IBM DB2 FireDAC.Phys.DB2.EDB2NativeException FireDAC.Phys.ODBCWrapper.TFDODBCNativeError
Informix FireDAC.Phys.Infx.EInfxNativeException FireDAC.Phys.Infx.TFDInfxError
InterBase FireDAC.Phys.IBWrapper.EIBNativeException FireDAC.Phys.IBWrapper.TFDIBError
Microsoft Access FireDAC.Phys.MSAcc.EMSAccessNativeException FireDAC.Phys.ODBCWrapper.TFDODBCNativeError
Microsoft SQL Server FireDAC.Phys.MSSQL.EMSSQLNativeException FireDAC.Phys.MSSQL.TFDMSSQLError
MySQL FireDAC.Phys.MySQLWrapper.EMySQLNativeException FireDAC.Phys.MySQLWrapper.TFDMySQLError
ODBC FireDAC.Phys.ODBCWrapper.EODBCNativeException FireDAC.Phys.ODBCWrapper.TFDODBCNativeError
Oracle FireDAC.Phys.OracleWrapper.EOCINativeException FireDAC.Phys.OracleWrapper.TOCIError
PostgreSQL FireDAC.Phys.PGWrapper.EPgNativeException FireDAC.Phys.PGWrapper.TFDPgError
SQLite FireDAC.Phys.SQLiteWrapper.ESQLiteNativeException FireDAC.Stan.Error.TFDDBError
Sybase SQL Anywhere FireDAC.Phys.ASAWrapper.EASANativeException FireDAC.Phys.ODBCWrapper.TFDODBCNativeError
Teradata Database FireDAC.Phys.TData.ETDataNativeException FireDAC.Phys.ODBCWrapper.TFDODBCNativeError

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 の以下のプロパティでも提供されます。

  • ErrorCode -- DBMS ベンダ固有のエラー コード
  • Kind -- DBMS に依存しないエラー種別
  • Message -- エラー メッセージ

アプリケーションのデバッグを簡単にするためや例外のログ記録をもっと有益なものにするため、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;

エンド ユーザー エラー ダイアログの使用

TFDGUIxErrorDialog コンポーネントを利用すると、エンド ユーザーは、データベースから返されたエラーの通知を受け取ることができます。

FireDACErrorPicture.png

このダイアログを使用するには、このコンポーネントをフォームのどこかにドロップするだけです。FireDAC の未処理の例外がある場合、このコンポーネントにより TApplication.OnException イベント ハンドラがフックされ、ダイアログがポップアップされます。ダイアログの[クエリ]ページでは、例外で生成された SQL コマンド テキストを参照できます。ダイアログで Ctrl+C キーを押すと、例外情報がすべてクリップボードにコピーされます。

関連項目