Verwenden von OLE DB-Fehlerobjekten (SQL Server Compact)

Wenn bei der Ausführung einer auf SQL Server Compact 3.5 basierenden Anwendung Fehler auftreten, wird vom OLE DB-Anbieter für SQL Server Compact 3.5 ein Array von Fehlerobjekten zurückgegeben und gespeichert. Auf diese Objekte kann dann auf die übliche Weise mithilfe von OLE DB zugegriffen werden. Der OLE DB-Anbieter für SQL Server Compact 3.5 gibt Fehler für jede vom Anbieter unterstützte Schnittstelle zurück. Weitere Informationen finden Sie unter Implementierte OLE DB-Schnittstellen (SQL Server Compact). Informationen zum allgemeinen Mechanismus für einen OLE DB-Client zum Abrufen von Fehlerinformationen finden Sie im Abschnitt über Microsoft OLE DB der Dokumentation für das Microsoft Data Access Components SDK (MDAC SDK) in der MSDN Library.

Beispiele

Das folgende Beispiel zeigt, wie die anbieterspezifischen Fehlernummern abgerufen werden können, wenn Sie den OLE DB-Anbieter für SQL Server Compact 3.5 verwenden.

Hinweis

Damit diese Beispielanwendung ausgeführt werden kann, muss sqlceoledb35.dll registriert sein. sqlceoledb35.dll kann in Windows mit dem Dienstprogramm regsvr32 von einer Befehlszeile aus registriert werden.

Hinweis

CLSID_SQLSERVERCE ist ein in der OLEDB-Headerdatei definiertes Makro, das CLSID_SQLSERVERCE_3_5 zugeordnet wird.

#include <windows.h>
#include <sqlce_oledb.h>
#include <sqlce_err.h>
#include <stdio.h>

/// <summary>
/// This function demonstrates a routine that can handle and display 
/// errors from the OLE DB provider for SQL Server Compact 3.5. The
/// errors that occured on the current thread are displayed.
/// </summary>

HRESULT DisplayCurrentThreadErrors()
{
    static TCHAR *sErrIErrorInfo     = L"IErrorInfo interface";
    static TCHAR *sErrIErrorRecords  = L"IErrorRecords interface";
    static TCHAR *sErrRecordCount    = L"error record count";
    static TCHAR *sErrInfo           = L"ERRORINFO structure";
    static TCHAR *sErrStandardInfo   = L"standard error info";
    static TCHAR *sErrDescription    = L"standard error description";
    static TCHAR *sErrNoSource       = L"error source";

    HRESULT hr                          = S_OK;
    IErrorInfo       *pIErrorInfo       = NULL;
    IErrorRecords    *pIErrorRecords    = NULL;
    ERRORINFO        errorInfo          = { 0 };
    IErrorInfo       *pIErrorInfoRecord = NULL;

    try
    {
        // This interface supports returning error information.
        // Get the error object from the system for the current
        // thread.
        hr = GetErrorInfo(0, &pIErrorInfo);
        if ( hr == S_FALSE )
        {
            wprintf(L"No error occured.\n");
            return S_OK;
        }

        if(FAILED(hr) || NULL == pIErrorInfo)
            throw sErrIErrorInfo;

        // The error records are retrieved from the IIErrorRecords
        // interface, which can be obtained from the IErrorInfo
        // interface.
        hr = pIErrorInfo->QueryInterface(IID_IErrorRecords,
            (void **) &pIErrorRecords);
        if ( FAILED(hr) || NULL == pIErrorRecords )
            throw sErrIErrorRecords;

        // The IErrorInfo interface is no longer required because
        // we have the IErrorRecords interface, relase it.
        pIErrorInfo->Release();
        pIErrorInfo = NULL;

        ULONG ulNumErrorRecs = 0;

        // Determine the number of records in this error object
        hr = pIErrorRecords->GetRecordCount(&ulNumErrorRecs);
        if ( FAILED(hr) )
            throw sErrRecordCount;


        // Loop over each error record in the error object to display 
        // information about each error. Errors are returned. 
        for (DWORD dwErrorIndex = 0;
             dwErrorIndex < ulNumErrorRecs;
             dwErrorIndex++)
        {
            // Retrieve basic error information for this error.
            hr = pIErrorRecords->GetBasicErrorInfo(dwErrorIndex,
              &errorInfo);
            if ( FAILED(hr) )
                throw sErrInfo;

            TCHAR szCLSID[64]  = { 0 };
            TCHAR szIID[64]    = { 0 };
            TCHAR szDISPID[64] = { 0 };

            StringFromGUID2(errorInfo.clsid, (LPOLESTR)szCLSID,
                sizeof(szCLSID));
            StringFromGUID2(errorInfo.iid, (LPOLESTR)szIID,
                sizeof(szIID));

            wprintf(L"HRESULT           = %lx\n", errorInfo.hrError);
            wprintf(L"clsid             = %s\n", szCLSID);
            wprintf(L"iid               = %s\n", szIID);
            wprintf(L"dispid            = %ld\n", errorInfo.dispid);
            wprintf(L"Native Error Code = %lx\n", errorInfo.dwMinor);

            // Retrieve standard error information for this error.
            hr = pIErrorRecords->GetErrorInfo(dwErrorIndex, NULL,
                &pIErrorInfoRecord);

            if ( FAILED(hr) )
                throw sErrStandardInfo;

            BSTR bstrDescriptionOfError;
            BSTR bstrSourceOfError;

            // Get the description of the error.
            hr = pIErrorInfoRecord->GetDescription(
                   &bstrDescriptionOfError);
            if ( FAILED(hr) )
                throw sErrDescription;

            wprintf(L"Description = %s\n", bstrDescriptionOfError);

            // Get the source of the error.
            hr = pIErrorInfoRecord->GetSource(&bstrSourceOfError);
            if ( FAILED(hr) )
                throw sErrNoSource;

            wprintf(L"Description = %s\n", bstrSourceOfError);

            // This interface variable will be used the next time 
            // though this loop. In the last error case this interface 
            // is no longer needed so we must release it.
            if(NULL != pIErrorInfoRecord)
                pIErrorInfoRecord->Release();
            pIErrorInfoRecord = NULL;
        }
    }
    catch( TCHAR *szMsg )
    {
        wprintf(L"Failed to retrieve ");
        wprintf(szMsg);
    }

    if( pIErrorInfoRecord )
        pIErrorInfoRecord->Release();

    if ( pIErrorInfo )
        pIErrorInfo->Release();

    if ( pIErrorRecords )
        pIErrorRecords->Release();

    return hr;
}

/// <summary>
/// This called will try to connect to a non existant
/// database to cause an error condition so that the call
/// to DisplayCurrentThreadError() has some errors to
/// display.
/// </summary>
/// <param="pIDBProperties">
/// IDBProperties interface that is used to set the properties on
/// for the Sql Compact engine object.
/// </param>
/// <param="pIDBInitialize">
/// Interface to the Sql Compact initialization object.
/// </param>

void CreateErrorCondition(IDBProperties *pIDBProperties,
                          IDBInitialize *pIDBInitialize)
{
    HRESULT     hr = S_OK;
    DBPROP      dbprop[1];
    DBPROPSET   dbpropset[1];

    VariantInit(&dbprop[0].vValue);

    // Initialize a property that uses name of database.
    dbprop[0].dwPropertyID   = DBPROP_INIT_DATASOURCE;
    dbprop[0].dwOptions      = DBPROPOPTIONS_REQUIRED;
    dbprop[0].vValue.vt      = VT_BSTR;
    dbprop[0].vValue.bstrVal = SysAllocString(L"t@#$94.SC5");

    // Initialize the property set.
    dbpropset[0].guidPropertySet = DBPROPSET_DBINIT;
    dbpropset[0].rgProperties    = dbprop;
    dbpropset[0].cProperties     = sizeof(dbprop)/sizeof(dbprop[0]);

    hr = pIDBProperties->SetProperties(
          sizeof(dbpropset)/sizeof(dbpropset[0]),
          dbpropset);
    VariantClear(&dbprop[0].vValue);

    if( FAILED(hr) )
        return;

    SysFreeString(dbprop[0].vValue.bstrVal);

    // This call will fail because the db does not exit.
    pIDBInitialize->Initialize();
}

/// <summary>
/// Application entry point initializes and cleans up the
/// needed interfaces and then calls the
/// DisplayCurrentThreadErrors() function to display error
/// information for the main application thread.
/// </summary>

void main()
{
    HRESULT hr                            = S_OK;
    IDBProperties     *pIDBProperties     = NULL;
    ISupportErrorInfo *pISupportErrorInfo = NULL;
    IDBInitialize     *pIDBInitialize     = NULL;
    BOOL bComInitialized                  = FALSE;

    try
    {
        hr = CoInitialize(NULL);
        if ( FAILED(hr) )
        {
            wprintf(L"CoInitialize failed");
            throw hr;
        }

        bComInitialized = TRUE;

        // Retrieve the SQL Compact edition initialization interface.
        hr = CoCreateInstance(CLSID_SQLSERVERCE,
                0,
                CLSCTX_INPROC_SERVER,
                IID_IDBInitialize,
                (void**)&pIDBInitialize);
        if( FAILED(hr) || NULL == pIDBInitialize )
        {
            wprintf(L"Failed to retrieve IDBInitialize Interface");
            throw hr;
        }

        // Retrieve the property interface, This interface will enable
        // setting of specific propertes on the SQL Server Compact
        //  engine object.
        hr = CoCreateInstance(CLSID_SQLSERVERCE,
            0,
            CLSCTX_INPROC_SERVER,
            IID_IDBProperties,
            (void**) &pIDBProperties);

        if( FAILED(hr) || NULL == pIDBProperties )
        {
            wprintf(L"Failed to retrieve IDBProperties Interface");
            throw hr;
        }

        hr = pIDBProperties->QueryInterface(IID_ISupportErrorInfo,
            (void**)&pISupportErrorInfo);

        if( FAILED(hr) || NULL == pISupportErrorInfo )
        {
            wprintf(L"Interface does not support ISupportErrorInfo");
            throw hr;
        }

        // Create an error condition by trying to open a non existance
        // datafile.
        CreateErrorCondition(pIDBProperties, pIDBInitialize);

        // Display errors that occured on the current (main) thread.
        hr = DisplayCurrentThreadErrors();
        if ( FAILED(hr) )
            throw hr;
    }
    catch( HRESULT hr)
    {
        wprintf(L", Error Code: %lx\n", hr);
    }

    if ( pISupportErrorInfo )
        pISupportErrorInfo->Release();

    if ( pIDBProperties )
        pIDBProperties->Release();

    if ( pIDBInitialize )
        pIDBInitialize->Release();

    if ( bComInitialized )
        CoUninitialize();
}

Siehe auch

Verweis

OLE DB-Anbieterreferenz (SQL Server Compact)

Hilfe und Informationen

Informationsquellen (SQL Server Compact 3.5 Service Pack 1)