この記事では、データベース例外を処理する方法について説明します。 この記事のほとんどの資料は、Open Database Connectivity (ODBC) の MFC クラスとデータ アクセス オブジェクト (DAO) の MFC クラスのどちらを使用しているかに関係なく適用されます。 一方または他のモデルに固有のマテリアルは明示的にマークされます。 ここでは、次の内容について説明します。
例外処理のアプローチ
この方法は、DAO (古い) と ODBC のどちらを使用しているかに関係なく同じです。
例外条件を処理するには、常に例外ハンドラーを記述する必要があります。
データベース例外をキャッチする最も実用的なアプローチは、例外シナリオでアプリケーションをテストすることです。 コード内の操作で発生する可能性のある例外を特定し、例外を強制的に発生させます。 次に、トレース出力を調べて、スローされる例外を確認するか、デバッガーで返されたエラー情報を調べます。 これにより、使用している例外シナリオに表示されるリターン コードを確認できます。
ODBC 例外に使用されるエラー コード
フォーム AFX_SQL_ERROR_XXXの名前を持つフレームワークによって定義されたリターン コードに加えて、一部の CDBException は ODBC リターン コードに基づいています。 このような例外のリターン コードには、フォーム SQL_ERROR_XXXの名前があります。
データベース クラスが返すことができるリターン コード (フレームワーク定義と ODBC 定義の両方) は、クラス CDBException
のm_nRetCode データ メンバーに記載されています。 ODBC で定義されたリターン コードに関する追加情報については、 ODBC プログラマーズ リファレンスを参照してください。
DAO 例外に使用されるエラー コード
DAO 例外の場合は、通常、より多くの情報を使用できます。 キャッチされた CDaoException オブジェクトの 3 つのデータ メンバーからエラー情報にアクセスできます。
m_pErrorInfo には、データベースに関連付けられている DAO のエラー オブジェクトのコレクションにエラー情報をカプセル化する CDaoErrorInfo オブジェクトへのポインターが含まれています。
m_nAfxDaoError には、MFC DAO クラスからの拡張エラー コードが含まれています。 フォーム AFX_DAO_ERROR_XXXの名前を持つこれらのエラー コードは、
CDaoException
のデータ メンバーの下に記載されています。m_scode DAO の OLE SCODE が含まれています (該当する場合)。 ただし、このエラー コードを操作する必要はほとんどありません。 通常、他の 2 つのデータ メンバーでは、より多くの情報を入手できます。 SCODE 値の詳細については、データ メンバーを参照してください。
DAO エラー、DAO Error オブジェクト型、および DAO Errors コレクションに関する追加情報は、 CDaoException クラスで使用できます。
データベース Exception-Handling の例
次の例では、new
演算子を使用してヒープ上に CRecordset 派生オブジェクトを構築し、レコードセットを開きます (ODBC データ ソースの場合)。 DAO クラスの同様の例については、以下の「DAO 例外の例」を参照してください。
ODBC 例外の例
Open メンバー関数は (ODBC クラスの CDBException 型の) 例外をスローする可能性があるため、このコードはtry
ブロックを使用してOpen
呼び出しを角かっこで囲みます。 後続の catch
ブロックは、 CDBException
をキャッチします。
e
と呼ばれる例外オブジェクト自体を調べることができますが、この場合、レコードセットの作成が失敗したことを把握するだけで十分です。
catch
ブロックは、メッセージ ボックスを表示し、レコードセット オブジェクトを削除してクリーンアップします。
CRecordset* CMyDatabaseDoc::GetRecordset()
{
CCourses* pSet = new CCourses(&m_dbCust);
try
{
pSet->Open();
}
catch (CDBException* e)
{
AfxMessageBox(e->m_strError, MB_ICONEXCLAMATION);
// Delete the incomplete recordset object
delete pSet;
pSet = NULL;
e->Delete();
}
return pSet;
}
DAO 例外の例
DAO の例は ODBC の例に似ていますが、通常は、より多くの種類の情報を取得できます。 次のコードでは、レコードセットの開き方も試みます。 その試行で例外がスローされた場合は、例外オブジェクトのデータ メンバーでエラー情報を調べることができます。 前の ODBC の例と同様に、レコードセットの作成が失敗したことを知るのに十分な可能性があります。
CDaoRecordset* CMyDaoDatabaseDoc::GetRecordset()
{
CDaoRecordset* pSet = new CCustSet(&m_db);
try
{
pSet->Open();
}
catch (CDaoException* pe)
{
AfxMessageBox(pe->m_pErrorInfo->m_strDescription, MB_ICONEXCLAMATION);
// Delete the incomplete recordset object
delete pSet;
pSet = NULL;
pe->Delete();
}
return pSet;
}
このコードは、例外オブジェクトの m_pErrorInfo メンバーからエラー メッセージ文字列を取得します。 MFC は、例外をスローするときにこのメンバーを塗りつぶします。
CDaoException
オブジェクトによって返されるエラー情報については、CDaoException クラスと CDaoErrorInfo クラスを参照してください。
Microsoft Jet (.mdb) データベースを使用している場合、ほとんどの場合、ODBC を使用している場合、エラー オブジェクトは 1 つだけになります。 まれに、ODBC データ ソースを使用していて、複数のエラーがある場合は、 CDaoException::GetErrorCount によって返されるエラーの数に基づいて DAO の Errors コレクションをループ処理できます。 ループを経るたびに 、CDaoException::GetErrorInfo を呼び出して、 m_pErrorInfo
データ メンバーをリフィルします。