OLE DB 오류 개체 사용(SQL Server Compact)

SQL Server Compact 4.0 기반 응용 프로그램을 실행하는 동안 오류가 발생하면 SQL Server Compact 4.0용 OLE DB 공급자는 오류 개체의 배열을 반환하고 저장합니다. 그러면 일반적인 방식으로 OLE DB를 사용하여 이들 개체에 액세스할 수 있습니다. SQL Server Compact용 OLE DB 공급자는 지원되는 각 인터페이스에 대한 오류를 반환합니다. 자세한 내용은 구현된 OLE DB 인터페이스(SQL Server Compact)를 참조하십시오. OLE DB 클라이언트에서 오류 정보를 검색하는 일반적인 메커니즘에 대한 자세한 내용은 MSDN Library에서 MDAC(Microsoft Data Access Components) SDK 설명서의 Microsoft OLE DB 섹션을 참조하십시오.

다음 예에서는 SQL Server Compact용 OLE DB 공급자를 사용할 때 공급자별 오류 번호를 검색하는 방법을 보여 줍니다.

참고 참고

이 예제 응용 프로그램을 실행하려면 sqlceoledb35.dll을 등록해야 합니다. sqlceoledb35.dll은 regsvr32 유틸리티를 사용하여 명령줄을 통해 Windows에 등록할 수 있습니다.

참고 참고

CLSID_SQLSERVERCE는 CLSID_SQLSERVERCE_3_5로 매핑되는 OLEDB 헤더 파일에 정의되어 있는 매크로입니다.

#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();
}
표시: