Поделиться через


Исключения: ошибки базы данных

В этой статье объясняется, как обрабатывать исключения базы данных. Большая часть материалов в этой статье относится к тому, работаете ли вы с классами MFC для Open Database Connectivity (ODBC) или MFC для объектов доступа к данным (DAO). Материал, характерный для одной или другой модели, явно помечен. Ниже приведены разделы:

Подходы к обработке исключений

Подход одинаков независимо от того, работаете ли вы с DAO (устаревшим) или ODBC.

Для обработки исключительных условий всегда надо писать обработчики исключений.

Наиболее прагматичным подходом к перехвату исключений базы данных является тестирование приложения с помощью сценариев исключений. Определите вероятные исключения, которые могут возникнуть для операции в коде, и принудительно выполните исключение. Затем просмотрите выходные данные трассировки, чтобы узнать, какое исключение выбрасывается, или ознакомьтесь с вернувшимися сведениями об ошибке в отладчике. Это позволяет узнать, какие коды возврата будут отображаться для сценариев исключений, которые вы используете.

Коды ошибок, используемые для исключений ODBC

Помимо кодов возврата, определенных платформой, которые имеют имена формы AFX_SQL_ERROR_XXX, некоторые CDBExceptions основаны на кодах возврата ODBC. Коды возврата для таких исключений имеют имена формы SQL_ERROR_XXX.

Коды возврата, как определяемые платформой, так и ODBC, которые классы баз данных могут возвращать, документированы в элементе данных m_nRetCode класса CDBException. Дополнительные сведения о кодах возврата, определенных ODBC, доступны в справочнике программиста ODBC.

Коды ошибок, используемые для исключений DAO

Для исключений DAO дополнительные сведения обычно доступны. Доступ к сведениям об ошибке можно получить через три члена данных пойманного объекта CDaoException.

  • m_pErrorInfo содержит указатель на объект CDaoErrorInfo , который инкапсулирует сведения об ошибке в коллекции объектов ошибок DAO, связанных с базой данных.

  • m_nAfxDaoError содержит расширенный код ошибки из классов DAO MFC. Эти коды ошибок, которые имеют имена формы AFX_DAO_ERROR_XXX, документируются в CDaoExceptionэлементе данных.

  • m_scode содержит OLE SCODE из DAO, если применимо. Однако вам редко придется работать с этим кодом ошибки. Обычно дополнительные сведения доступны в двух других элементах данных. Дополнительные сведения о значениях SCODE см. в элементе данных.

Дополнительные сведения об ошибках DAO, тип объекта DAO Error и коллекция ошибок DAO доступна в классе CDaoException.

Пример Exception-Handling базы данных

В следующем примере выполняется попытка создать производный от CRecordset объект в куче с new оператором, а затем открыть набор записей (для источника данных ODBC). Аналогичный пример для классов DAO см. в разделе "Пример исключения DAO" ниже.

Пример исключения ODBC

Функция-член Open может вызвать исключение (типа CDBException для классов ODBC), поэтому этот код заключает вызов 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 и существует несколько ошибок, можно выполнить цикл по коллекции ошибок DAO в зависимости от количества ошибок, возвращаемых CDaoException::GetErrorCount. Каждый раз через цикл вызовите CDaoException::GetErrorInfo для повторного m_pErrorInfo заполнения элемента данных.

См. также

обработка исключений