异常:数据库异常

本文介绍如何处理数据库异常。 本文中的大多数材料都适用于开放数据库连接(ODBC)的 MFC 类或数据访问对象(DAO)的 MFC 类。 特定于一个或另一个模型的材料被显式标记。 主题包括:

异常处理方法

无论使用的是 DAO(已过时)还是 ODBC,此方法都是相同的。

应始终编写异常处理程序来处理异常情况。

捕获数据库异常的最务实方法是使用异常方案测试应用程序。 确定代码中作可能发生的异常,并强制发生异常。 然后检查跟踪输出以查看引发的异常,或检查调试器中返回的错误信息。 这可让你知道将针对所使用的异常方案看到的返回代码。

用于 ODBC 异常的错误代码

除了框架定义的返回代码(具有表单 名称AFX_SQL_ERROR_XXX),某些 CDBException 还基于 ODBC 返回代码。 此类异常的返回代码具有表单 SQL_ERROR_XXX的名称。

数据库类可以返回的返回代码(框架定义和 ODBC 定义)记录在类CDBExceptionm_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),因此此代码将调用括在块tryOpen。 后续 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 的错误信息的讨论,请参阅 CDaoExceptionCDaoErrorInfo 类。

使用 Microsoft Jet (.mdb) 数据库时,大多数情况下使用 ODBC 时,只有一个错误对象。 在极少数情况下,使用 ODBC 数据源并出现多个错误时,可以根据 CDaoException::GetErrorCount 返回的错误数循环访问 DAO 的错误集合。 每次通过循环时,调用 CDaoException::GetErrorInfo 以重新填充 m_pErrorInfo 数据成员。

另请参阅

异常处理