例外処理 : データベースの例外
ここでは、データベース例外の処理方法について説明します。 この項は、ODBC と DAO の両方が対象です。 片方だけを対象とした説明箇所は、その旨を明記しています。 ここでは、次の内容について説明します。
例外処理の方法
データベースの例外処理の例
例外処理の方法
例外処理方法は、DAO でも ODBC でも同じです。
例外条件を処理するときは、必ず例外ハンドラーを作成します。
データベース例外をキャッチする最も現実的な方法は、例外の起きる状態でアプリケーションをテストすることです。 頻繁に発生しそうな例外を特定し、実際にその例外を発生させます。 トレース出力を調べると、スローされた例外とデバッガーが返したエラー情報を調べることができます。 これによって、例外状況で返される戻り値がわかります。
ODBC 例外処理に使うエラー コード
フレームワークで定義されている AFX_SQL_ERROR_XXX 形式の名前の戻り値のほか、ODBC 戻り値に基づく CDBException があります。 戻り値 CDBException の名前は、SQL_ERROR_XXX 形式です。
データベース クラスが返すフレームワーク定義の戻り値と ODBC 定義の戻り値については、CDBException クラスのデータ メンバー「CDBException::m_nRetCode」を参照してください。 ODBC 定義の戻り値の詳細については、MSDN ライブラリの『ODBC SDK Programmer's Reference』を参照してください。
DAO 例外に使うエラー コード
DAO 例外では、通常、ODBC より多くの情報を得られます。 キャッチした CDaoException オブジェクトの 3 つのデータ メンバーを通じてエラー情報にアクセスできるからです。
m_pErrorInfo では、CDaoErrorInfo オブジェクトを指すポインターを指定します。このオブジェクトでは、データベースに関連付けられているエラー オブジェクトの DAO コレクションにエラー情報をカプセル化しています。
m_nAfxDaoError は、MFC DAO クラスの拡張エラー コードを保持します。 この種のエラー コードには、AFX_DAO_ERROR_XXX 形式の名前が付いています。CDaoException のデータ メンバーを参照してください。
m_scode は、DAO の OLE SCODE を保持します。 ただし、このエラー コードを使うことはほとんどありません。 通常は、上の 2 つのデータ メンバーで十分な情報を得られます。 SCODE 値の詳細については、このデータ メンバーを参照してください。
DAO エラー、DAO エラー オブジェクトの型、および DAO エラー コレクションの詳細については、「CDaoException クラス」を参照してください。
データベースの例外処理の例
次に、new 演算子でヒープ上に CRecordset の派生クラスを作成し、レコードセットを開く例を示します。この説明は、ODBC データ ソースが対象です。 DAO クラスを使う場合は、「DAO 例外の例」を参照してください。
ODBC 例外の例
メンバー関数 Open は、ODBC クラスの CDBException をスローすることがあるので、Open の呼び出しを try ブロックで囲みます。 その後の 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 の例と似ていますが、通常、DAO の方が多くの情報を得られます。 次の例では、レコードセットを開こうとしています。 例外がスローされた場合は、例外オブジェクトのデータ メンバーでエラー情報を確認できます。 上の 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) データベースの使用中に発生するエラー オブジェクトは 1 つだけです。ODBC の使用中に発生するエラーも、ほとんどの場合は 1 つだけです。 ただし、ODBC データ ソースの使用中に複数のエラーが発生することもあります。この場合は、CDaoException::GetErrorCount が返したエラー数に応じて、DAO のエラー コレクションに対してループを行います。 ループ」するつど、CDaoException::GetErrorInfo を呼び出して m_pErrorInfo データ メンバーを再設定します。