Так исторически сложилось, что c базой данных мне приходится работать через OLE DB. Для получения текстовых сообщений об ошибках взаимодействия с БД можно использовать замечательную функцию AtlTraceErrorRecords. Эта функция выводит подробную информацию об ошибке на нужном языке, но работает только в отладочной сборке и выводит сообщения не в наш лог, что, очевидно, не очень удобно. Доработать эту функцию несложно, т.к. она предоставляется в исходных кодах в файле atldbcli.h. После доработки выглядит она следующим образом:
namespace DBUtils { CString TraceErrorRecords(HRESULT hrErr) const { CDBErrorInfo ErrorInfo; ULONG cRecords; HRESULT hr; ULONG i; CComBSTR bstrDesc, bstrHelpFile, bstrSource; GUID guid; DWORD dwHelpContext; WCHAR wszGuid[40]; CString msg; // If the user passed in an HRESULT then trace it if (hrErr != S_OK) SystemLog<LOG_DEBUG > (L"OLE DB Error Record dump for hr = 0x%x") % hrErr; LCID lcLocale = GetSystemDefaultLCID(); hr = ErrorInfo.GetErrorRecords(&cRecords); if (FAILED(hr) && ErrorInfo.m_spErrorInfo == NULL) { SystemLog<LOG_DEBUG>(L"No OLE DB Error Information found: hr = 0x%x") % hr; } else { for (i = 0; i < cRecords; i++) { hr = ErrorInfo.GetAllErrorInfo(i, lcLocale, &bstrDesc, &bstrSource, &guid, &dwHelpContext, &bstrHelpFile); if (FAILED(hr)) { SystemLog<LOG_DEBUG>(L"OLE DB Error Record dump retrieval failed: hr = 0x%x") % hr; return msg; } StringFromGUID2(guid, wszGuid, sizeof(wszGuid) / sizeof(WCHAR)); CString tmpMsg; tmpMsg.Format(_T("Row #: %4d Source: \"%s\" Description: \"%s\" Help File: \"%s\" Help Context: %4d GUID: %s\n"), i, OLE2T(bstrSource), OLE2T(bstrDesc), OLE2T(bstrHelpFile), dwHelpContext, OLE2T(wszGuid)); SystemLog<LOG_DEBUG>(tmpMsg); bstrSource.Empty(); bstrDesc.Empty(); bstrHelpFile.Empty(); msg += tmpMsg; } SystemLog<LOG_DEBUG>(L"OLE DB Error Record dump end"); } return msg; } }//namespace DBUtilsДля сохранения в файл здесь используется уже описанная ранее функция SystemLog. В результате в файл сохраняются сообщения, которые легко понять даже пользователю. Результат функции также можно использовать в окне Task Dialog в разделе с дополнительной технической информацией.