本文介绍如何处理数据库异常。 本文中的大多数材料都适用于开放数据库连接(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 对象的三个数据成员访问错误信息:
m_pErrorInfo 包含指向 CDaoErrorInfo 对象的指针,该对象封装 DAO 与数据库关联的错误对象集合中的错误信息。
m_nAfxDaoError 包含 MFC DAO 类中的扩展错误代码。 这些错误代码包含表单 AFX_DAO_ERROR_XXX的名称,这些错误代码记录在数据成员的下方
CDaoException
。m_scode 包含 DAO 中的 OLE SCODE (如果适用)。 但是,你很少需要使用此错误代码。 通常,其他两个数据成员中提供了更多信息。 有关 SCODE 值的详细信息,请参阅数据成员。
有关 DAO 错误、DAO 错误对象类型和 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 时,只有一个错误对象。 在极少数情况下,使用 ODBC 数据源并出现多个错误时,可以根据 CDaoException::GetErrorCount 返回的错误数循环访问 DAO 的错误集合。 每次通过循环时,调用 CDaoException::GetErrorInfo 以重新填充 m_pErrorInfo
数据成员。