OLE DB Programmer's Reference |
When an error occurs in a provider, the provider can return an OLE DB error object to describe that error. To do this, it should perform the following actions:
The following code shows an example of how a provider that is unable to open a table might respond by creating an OLE DB error object and transferring ownership of the object to the Automation DLL:
#include <oledb.h> DWORD errCantOpenTable; IOpenRowset * pSimpleProvider; IRowset * pRowset; DBID TableID; extern GUID CLSID_THISISAM; extern DISPID DISPID_OpenRowset; BSTR bstrTableName; int main() { IClassFactory * pErrorObjectFactory; ERRORINFO ErrorInfo; HRESULT hr, hrErr; IErrorInfo * pErrorInfo; IErrorRecords * pErrorRecords; // Clear the current error object. SetErrorInfo(0, NULL); // Try to open the table or call another provider to do it. hrErr = pSimpleProvider->OpenRowset(NULL, &TableID, NULL, IID_IRowset, 0, NULL, (IUnknown**) &pRowset); if (!FAILED(hrErr)) return hrErr; // An error or warning occurred while opening the table. // Get the current error object. If one does not exist, // create a new one. GetErrorInfo(0, &pErrorInfo); if (!pErrorInfo) { CoGetClassObject(CLSID_EXTENDEDERRORINFO, CLSCTX_INPROC_SERVER, NULL, // Reserved, must be NULL IID_IClassFactory, (LPVOID *)&pErrorObjectFactory); hr = pErrorObjectFactory->CreateInstance(NULL, IID_IErrorInfo, (void**) &pErrorInfo); } // Get an IErrorRecords interface pointer on the error object. hr = pErrorInfo->QueryInterface(IID_IErrorRecords, (void**) &pErrorRecords); // Set up a parameter to pass to the object. VARIANTARG varg; VariantInit (&varg); DISPPARAMS dispparams = {&varg, NULL, 1, 0}; varg.vt = VT_BSTR; varg.bstrVal = SysAllocString(bstrTableName); // Fill in the ERRORINFO structure and add the error record. ErrorInfo.hrError = hrErr; ErrorInfo.dwMinor = errCantOpenTable; ErrorInfo.clsid = CLSID_THISISAM; ErrorInfo.iid = IID_IOpenRowset; ErrorInfo.dispid = DISPID_OpenRowset; hr = pErrorRecords-> AddErrorRecord(&ErrorInfo,ErrorInfo.dwMinor,&dispparams,NULL,0); VariantClear(&varg); // Call SetErrorInfo to pass the error object to the Automation DLL. hr = SetErrorInfo(0, pErrorInfo); // Release the interface pointers on the object to finish transferring // ownership ofthe object to the Automation DLL. pErrorRecords->Release(); pErrorInfo->Release(); if(pErrorObjectFactory) pErrorObjectFactory->Release(); return hr; };
The following code example shows how a provider adds a record to an OLE DB error object that includes a pointer to a custom error object:
#include <oledb.h> class CSQLStateObject:public ISQLErrorInfo { public: CSQLStateObject(OLECHAR ); CSQLStateObject(); HRESULT __stdcall QueryInterface(REFIID, void** ); ULONG __stdcall AddRef(void); ULONG __stdcall Release(void); HRESULT __stdcall GetSQLInfo( /* [out] */ BSTR __RPC_FAR *pbstrSQLState, /* [out] */ LONG __RPC_FAR *plNativeError); }; extern DISPID DISPID_GetData; extern GUID CLSID_THISISAM; DWORD errGeneralError; int main() { IClassFactory * pErrorObjectFactory; ERRORINFO ErrorInfo; HRESULT hr, hrErr; IErrorInfo * pErrorInfo; IErrorRecords * pErrorRecords; // Clear the current error object. SetErrorInfo(0, NULL); // (Not shown.) Do something that causes an error to occur. if (!FAILED(hrErr)) return hrErr; // An error or warning occurred. Get the current error object. // If one does not exist, create one. GetErrorInfo(0, &pErrorInfo); CoGetClassObject(CLSID_EXTENDEDERRORINFO, CLSCTX_INPROC_SERVER, NULL, // Reserved, must be NULL IID_IClassFactory, (LPVOID *)&pErrorObjectFactory)); if (!pErrorInfo) hr = pErrorObjectFactory->CreateInstance(NULL, IID_IErrorInfo, (void**) &pErrorInfo); // Get an IErrorRecords interface pointer on the error object. hr = pErrorInfo->QueryInterface(IID_IErrorRecords, (void**) &pErrorRecords); // Create a custom error object. CSQLStateObject* pMyErrObj = new CSQLStateObject(OLESTR("HY000")); // Fill in the ERRORINFO structure and add the error record. ErrorInfo.hrError = hrErr; ErrorInfo.dwMinor = errGeneralError; ErrorInfo.clsid = CLSID_THISISAM; ErrorInfo.iid = IID_IRowset; ErrorInfo.dispid = DISPID_GetData; hr = pErrorRecords->AddErrorRecord(&ErrorInfo, ErrorInfo.dwMinor, NULL, (void**) pMyErrObj, 0); // Release the interface pointer on the custom error object // to finish transferring ownership of it to the error object. pMyErrObj->Release(); // Call SetErrorInfo to pass the error object to the Automation DLL. hr = SetErrorInfo(0, pErrorInfo); // Release the interface pointers on the object to finish // transferring ownership of the object to the Automation DLL. pErrorRecords->Release(); pErrorInfo->Release(); pErrorObjectFactory->Release(); return hr; };
1998-2001 Microsoft Corporation. All rights reserved.