异常:数据库异常
本文介绍如何处理数据库异常。 无论是使用开放式数据库连接 (ODBC) 的 MFC 类还是数据访问对象 (DAO) 的 MFC 类,本文中的大部分材料都适用。 特定于一个或多个模型的材料被显式标记。 主题包括:
异常处理方法
无论使用的是 DAO(已过时)还是 ODBC,方法都是一样的。
应始终编写异常处理程序来处理异常情况。
捕获数据库异常最实用的方法是用异常场景测试应用程序。 确定代码中的操作可能发生的异常,并强制异常发生。 然后检查跟踪输出以查看引发的异常,或检查调试器中返回的错误信息。 这样,便可以了解将在所使用的异常场景中看到哪些返回代码。
用于 ODBC 异常的错误代码
除了框架定义的返回代码(其名称格式为 AFX_SQL_ERROR_XXX)之外,一些 CDBExceptions 还基于 ODBC 返回代码。 此类异常的返回代码名称格式为 SQL_ERROR_XXX。
数据库类可以返回的返回代码(框架定义和 ODBC 定义)记录在类 CDBException
的 m_nRetCode 数据成员下。 ODBC 程序员参考中提供了有关 ODBC 定义的返回代码的其他信息。
用于 DAO 异常的错误代码
对于 DAO 异常,通常会提供更多信息。 可以通过捕获的 CDaoException 对象的三个数据成员访问错误信息:
m_pErrorInfo 包含一个指向 CDaoErrorInfo 对象的指针,该对象将错误信息封装在 DAO 的与数据库关联的错误对象集合中。
m_nAfxDaoError 包含来自 MFC DAO 类的扩展错误代码。 这些错误代码的名称格式为 AFX_DAO_ERROR_XXX,记录在
CDaoException
中的数据成员下。m_scode 包含来自 DAO 的 OLE SCODE(如果适用)。 但是,你很少需要使用此错误代码。 通常在其他两个数据成员处可以获得详细信息。 有关 SCODE 值的详细信息,请参阅数据成员。
CDaoException 类下提供了有关 DAO 错误、DAO 错误对象类型和 DAO 错误集合的其他信息。
数据库异常处理示例
下面的示例尝试使用 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 示例类似,但你通常可以检索更多种类的信息。 以下代码还尝试打开记录集。 如果该尝试引发异常,可以检查异常对象的数据成员以获取错误信息。 与前面的 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 的大多数情况下,将只有一个错误对象。 在极少数情况下,使用 ODBC 数据源并且存在多个错误时,可以根据 CDaoException::GetErrorCount 返回的错误数循环访问 DAO 的错误集合。 每次循环时,调用 CDaoException::GetErrorInfo 以重新填充 m_pErrorInfo
数据成员。