Exceções: exceções de banco de dados

Este artigo explica como lidar com exceções de banco de dados. A maior parte do material neste artigo se aplica se você está trabalhando com as classes MFC para ODBC ou as classes MFC para DAO (Objetos de Acesso a Dados). O material específico de um ou outro modelo está explicitamente marcado. Os tópicos incluem:

Abordagens para tratamento de exceções

A abordagem é a mesma se você estiver trabalhando com DAO (obsoleto) ou ODBC.

Você deve sempre escrever manipuladores de exceção para lidar com condições excepcionais.

A abordagem mais pragmática para capturar exceções de banco de dados é testar seu aplicativo com cenários de exceção. Determine as exceções prováveis que possam ocorrer para uma operação em seu código e force a exceção a ocorrer. Em seguida, examine a saída de rastreamento para ver qual exceção é gerada ou examine as informações de erro retornadas no depurador. Isso permite que você saiba quais códigos de retorno você verá para os cenários de exceção que você está usando.

Códigos de erro usados para exceções ODBC

Além de retornar códigos definidos pela estrutura, que têm nomes do formulário AFX_SQL_ERROR_XXX, algumas CDBExceptions são baseadas em códigos de retorno ODBC. Os códigos de retorno para essas exceções têm nomes de formulário SQL_ERROR_XXX.

Os códigos de retorno, definidos pelo Framework e definidos pelo ODBC, que as classes de banco de dados podem retornar são documentados sob o membro de dados m_nRetCode de classe CDBException. Informações adicionais sobre códigos de retorno definidos pelo ODBC estão disponíveis na Referência do Programador ODBC.

Códigos de erro usados para exceções de DAO

Para exceções de DAO, normalmente estão disponíveis mais informações. Você pode acessar informações de erro por meio de três membros de dados de um objeto CDaoException capturado:

  • m_pErrorInfo contém um ponteiro para um objeto CDaoErrorInfo que encapsula informações de erro na coleção de objetos de erro do DAO associados ao banco de dados.

  • m_nAfxDaoError contém um código de erro estendido das classes DAO do MFC. Esses códigos de erro, que têm nomes de formulário AFX_DAO_ERROR_XXX, são documentados no membro de dados em CDaoException.

  • m_scode contém um SCODE OLE do DAO, caso aplicável. No entanto, você raramente precisará trabalhar com esse código de erro. Normalmente, mais informações estão disponíveis nos outros dois membros de dados. Consulte o membro de dados para obter mais informações sobre valores SCODE.

Informações adicionais sobre erros de DAO, o tipo de objeto Erro de DAO e a coleção Erros de DAO estão disponíveis na classe CDaoException.

Um exemplo de tratamento de exceções de banco de dados

O exemplo a seguir tenta construir um objeto derivado de CRecordset no heap com o operador new e, em seguida, abrir o conjunto de registros (para uma fonte de dados ODBC). Para obter um exemplo semelhante para as classes DAO, consulte "Exemplo de exceção de DAO" abaixo.

Exemplo de exceção ODBC

A função membro Open pode gerar uma exceção (do tipo CDBException para as classes ODBC), portanto, esse código coloca a chamada Open entre colchetes com um bloco try. O bloco catch subsequente capturará um CDBException. Você pode examinar o objeto de exceção em si, chamado e, mas nesse caso é suficiente saber que a tentativa de criar um conjunto de registros falhou. O bloco catch exibe uma caixa de mensagem e limpa excluindo o objeto de conjunto de registros.

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;
}

Exemplo de exceção de DAO

O exemplo de DAO é semelhante ao exemplo de ODBC, mas normalmente você pode recuperar mais tipos de informações. O código a seguir também tenta abrir um conjunto de registros. Se essa tentativa gerar uma exceção, você poderá examinar um membro de dados do objeto de exceção para obter informações do erro. Assim como no exemplo anterior do ODBC, provavelmente é suficiente saber que a tentativa de criar um conjunto de registros falhou.

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;
}

Esse código obtém uma cadeia de caracteres da mensagem de erro do membro m_pErrorInfo do objeto de exceção. O MFC preenche esse membro quando ele lança a exceção.

Para obter uma discussão sobre as informações de erro retornadas por um objeto CDaoException, consulte as classes CDaoException e CDaoErrorInfo.

Quando você estiver trabalhando com bancos de dados do Microsoft Jet (.mdb) e, na maioria dos casos, quando estiver trabalhando com o ODBC, haverá apenas um objeto de erro. No raro caso de você estar usando uma fonte de dados ODBC e ocorrerem vários erros, você poderá executar um loop por meio da coleção Erros de DAO com base no número de erros retornados por CDaoException::GetErrorCount. Sempre que passar pelo loop, chame CDaoException::GetErrorInfo para recarregar o membro de dados m_pErrorInfo.

Confira também

Tratamento de exceção