Undantag: Databasundantag

Den här artikeln beskriver hur du hanterar databasfel. Det mesta av materialet i den här artikeln gäller oavsett om du arbetar med MFC-klasserna för Open Database Connectivity (ODBC) eller MFC-klasserna för dataåtkomstobjekt (DAO). Material som är specifikt för den ena eller den andra modellen är uttryckligen markerat. Ämnena omfattar:

Metoder för undantagshantering

Metoden är densamma oavsett om du arbetar med DAO (föråldrad) eller ODBC.

Du bör alltid skriva undantagshanterare för att hantera exceptionella villkor.

Den mest pragmatiska metoden för att fånga databasundantag är att testa ditt program med undantagsscenarier. Fastställ de troliga undantag som kan inträffa för en åtgärd i koden och tvinga fram undantaget. Granska sedan spårningsutdata för att se vilket undantag som utlöses eller granska den returnerade felinformationen i felsökningsprogrammet. På så sätt vet du vilka returkoder du ser för de undantagsscenarier som du använder.

Felkoder som används för ODBC-undantag

Förutom returkoder som definierats av ramverket, som har namn på formuläret AFX_SQL_ERROR_XXX, baseras vissa CDBExceptionsODBC-returkoder . Returkoderna för sådana undantag har namn på formuläret SQL_ERROR_XXX.

Returkoderna – både ramverksdefinierade och ODBC-definierade – som databasklasserna kan returnera dokumenteras under m_nRetCode datamedlem i klassen CDBException. Ytterligare information om returkoder som definierats av ODBC finns i ODBC-programmerarens referens.

Felkoder som används för DAO-undantag

För DAO-undantag är mer information vanligtvis tillgänglig. Du kan komma åt felinformation via tre datamedlemmar i ett fångat CDaoException-objekt :

  • m_pErrorInfo innehåller en pekare till ett CDaoErrorInfo-objekt som kapslar in felinformation i DAO:s samling av felobjekt som är associerade med databasen.

  • m_nAfxDaoError innehåller en utökad felkod från MFC DAO-klasserna. Dessa felkoder, som har namn i formatet AFX_DAO_ERROR_XXX, finns dokumenterade under datamedlemmen i CDaoException.

  • m_scode innehåller en OLE SCODE från DAO, om tillämpligt. Du behöver dock sällan arbeta med den här felkoden. Vanligtvis finns mer information tillgänglig i de andra två datamedlemmarna. Se datamedlemmen för mer information om SCODE-värden.

Ytterligare information om DAO-fel, objekttypen DAO-fel och samlingen DAO-fel är tillgänglig under klassen CDaoException.

Exempel på en databas Exception-Handling

I följande exempel görs ett försök att konstruera ett objekt härlett från CRecordset på heapen med hjälp av new-operatorn, och sedan öppna postuppsättningen (för en ODBC-datakälla). Ett liknande exempel för DAO-klasserna finns i "EXEMPEL på DAO-undantag" nedan.

Exempel på ODBC-undantag

Medlemsfunktionen Open kan utlösa ett undantag (av typen CDBException för ODBC-klasserna), så den här koden omger anropet Open med ett try block. Det efterföljande catch blocket kommer att fånga en CDBException. Du kan undersöka själva undantagsobjektet med namnet e, men i det här fallet räcker det att veta att försöket att skapa en postuppsättning har misslyckats. Blocket catch visar en meddelanderuta och rensar genom att ta bort postuppsättningsobjektet.

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

Exempel på DAO-undantag

DAO-exemplet liknar exemplet för ODBC, men du kan vanligtvis hämta fler typer av information. Följande kod försöker också öppna en postuppsättning. Om det försöket utlöser ett undantag kan du undersöka en datamedlem i undantagsobjektet efter felinformation. Precis som i det tidigare ODBC-exemplet är det förmodligen tillräckligt att veta att försöket att skapa en recordset misslyckades.

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

Den här koden hämtar en felmeddelandesträng från m_pErrorInfo medlem i undantagsobjektet. MFC fyller den här medlemmen när den utlöser undantaget.

En diskussion om felinformationen som returneras av ett CDaoException objekt finns i klasserna CDaoException och CDaoErrorInfo.

När du arbetar med Microsoft Jet-databaser (.mdb) och i de flesta fall när du arbetar med ODBC finns det bara ett felobjekt. I sällsynta fall när du använder en ODBC-datakälla och det finns flera fel kan du loopa igenom DAO:s felsamling baserat på antalet fel som returneras av CDaoException::GetErrorCount. Varje gång genom loopen, anropa CDaoException::GetErrorInfo för att uppdatera m_pErrorInfo datafältet.

Se även

undantagshantering