How to fetch rows from a result set (OLE DB)

To fetch rows from a result set

/*

    Example shows how to fetch rows from a result set.

*/

void InitializeAndEstablishConnection();

void ProcessResultSet();

  

#define UNICODE

#define _UNICODE

#define DBINITCONSTANTS

#define INITGUID

  

#include <stdio.h>

#include <tchar.h>

#include <stddef.h>

#include <windows.h>

#include <iostream.h>

#include <oledb.h>

#include <SQLOLEDB.h>

  

IDBInitialize*       pIDBInitialize     = NULL;

IDBProperties*       pIDBProperties     = NULL;

IDBCreateSession*    pIDBCreateSession  = NULL;

IDBCreateCommand*    pIDBCreateCommand  = NULL;

ICommandText*        pICommandText      = NULL;

IRowset*             pIRowset           = NULL;

IColumnsInfo*        pIColumnsInfo      = NULL;

DBCOLUMNINFO*        pDBColumnInfo      = NULL;

IAccessor*           pIAccessor        =  NULL;

DBPROP               InitProperties[4];

DBPROPSET            rgInitPropSet[1];

ULONG                i, j;

HRESULT              hr;

LONG                 cNumRows = 0;

ULONG                lNumCols;

WCHAR*               pStringsBuffer;

DBBINDING*           pBindings;

ULONG                ConsumerBufColOffset = 0;

HACCESSOR            hAccessor;

ULONG                lNumRowsRetrieved;

HROW                 hRows[10];

HROW*                pRows = &hRows[0];

BYTE*                pBuffer;

  

void main() {

  

    //Here is the command to execute.

    WCHAR* wCmdString

        = OLESTR(" SELECT title, price FROM titles WHERE royalty > 14");

  // Call a function to initialize and establish connection.

    InitializeAndEstablishConnection();

  

    //Create a session object.

    if(FAILED(pIDBInitialize->QueryInterface(

                                IID_IDBCreateSession,

                                (void**) &pIDBCreateSession)))

    {

        cout << "Failed to obtain IDBCreateSession interface.\n";

    }

  

    if(FAILED(pIDBCreateSession->CreateSession(

                                     NULL,

                                     IID_IDBCreateCommand,

                                     (IUnknown**) &pIDBCreateCommand)))

    {

        cout << "pIDBCreateSession->CreateSession failed.\n";

    }

  

    //Access the ICommandText interface.

    if(FAILED(pIDBCreateCommand->CreateCommand(

                                    NULL,

                                    IID_ICommandText,

                                    (IUnknown**) &pICommandText)))

    {

        cout << "Failed to access ICommand interface.\n";

    }

    

    //Use SetCommandText() to specify the command text.

    if(FAILED(pICommandText->SetCommandText(DBGUID_DBSQL, wCmdString)))

    {

        cout << "Failed to set command text.\n";

    }

  

    //Execute the command.

    if(FAILED(hr = pICommandText->Execute(NULL,

                                    IID_IRowset,

                                    NULL,

                                    &cNumRows,

                                    (IUnknown **) &pIRowset)))

    {

        cout << "Failed to execute command.\n";

    }

  

    //Process the result set.

    ProcessResultSet();

                        

    pIRowset->Release();

  

    //Free up memory.

    pICommandText->Release();

    pIDBCreateCommand->Release();

    pIDBCreateSession->Release();

    

    if(FAILED(pIDBInitialize->Uninitialize()))

    {

        /*Uninitialize is not required, but it fails if an interface

        has not been released.  This can be used for debugging.

        cout << "Problem uninitializing.\n"; */

    } //endif.

    pIDBInitialize->Release();

    

    //Release the COM library.

    CoUninitialize();

};

//--------------------------------------------------------------------

void InitializeAndEstablishConnection()

{   

    //Initialize the COM library.

    CoInitialize(NULL);

  

    //Obtain access to the SQLOLEDB provider.

    hr = CoCreateInstance(CLSID_SQLOLEDB,

                          NULL,

                          CLSCTX_INPROC_SERVER,

                          IID_IDBInitialize,

                          (void **) &pIDBInitialize);

    if(FAILED(hr))

    {

        printf("Failed to get IDBInitialize interface.\n");

    } //end if

  

    /*

    Initialize the property values needed

    to establish the connection.

    */

    for(i = 0; i < 4; i++)

        VariantInit(&InitProperties[i].vValue);

    

  

    //Server name.

    InitProperties[0].dwPropertyID  = DBPROP_INIT_DATASOURCE;

    InitProperties[0].vValue.vt     = VT_BSTR;

    InitProperties[0].vValue.bstrVal=

                            SysAllocString(L"server");

    InitProperties[0].dwOptions     = DBPROPOPTIONS_REQUIRED;

    InitProperties[0].colid         = DB_NULLID;

  

//Database.

    InitProperties[1].dwPropertyID  = DBPROP_INIT_CATALOG;

    InitProperties[1].vValue.vt     = VT_BSTR;

    InitProperties[1].vValue.bstrVal= SysAllocString(L"database");

    InitProperties[1].dwOptions     = DBPROPOPTIONS_REQUIRED;

    InitProperties[1].colid         = DB_NULLID;

  

//Username (login).

    InitProperties[2].dwPropertyID  = DBPROP_AUTH_USERID;

    InitProperties[2].vValue.vt     = VT_BSTR;

    InitProperties[2].vValue.bstrVal= SysAllocString(L"login");

    InitProperties[2].dwOptions     = DBPROPOPTIONS_REQUIRED;

    InitProperties[2].colid         = DB_NULLID;

  

//Password.

    InitProperties[3].dwPropertyID  = DBPROP_AUTH_PASSWORD;

    InitProperties[3].vValue.vt     = VT_BSTR;

    InitProperties[3].vValue.bstrVal= SysAllocString(L"Password");

    InitProperties[3].dwOptions     = DBPROPOPTIONS_REQUIRED;

    InitProperties[3].colid         = DB_NULLID;

  

    /*

    Now that the properties are set, construct the DBPROPSET structure

    (rgInitPropSet). The DBPROPSET structure is used to pass an array

    of DBPROP structures (InitProperties) to the SetProperties method.

    */

    rgInitPropSet[0].guidPropertySet = DBPROPSET_DBINIT;

    rgInitPropSet[0].cProperties    = 4;

    rgInitPropSet[0].rgProperties   = InitProperties;

  

    //Set initialization properties.

    hr = pIDBInitialize->QueryInterface(IID_IDBProperties,

                                   (void **)&pIDBProperties);

    if(FAILED(hr))

    {

        cout << "Failed to get IDBProperties interface.\n";

    }

  

    hr = pIDBProperties->SetProperties(1, rgInitPropSet);

    if(FAILED(hr))

    {

        cout << "Failed to set initialization properties.\n";

    } //end if

  

    pIDBProperties->Release();

  

    //Now establish the connection to the data source.

    if(FAILED(pIDBInitialize->Initialize()))

    {

        cout << "Problem in establishing connection to the data

        source.\n";

    }

} //end of InitializeAndEstablishConnection.

//--------------------------------------------------------------------

//Retrieve and display data resulting from a query.

void ProcessResultSet()

{

    //Obtain access to the IColumnInfo interface, from the Rowset

    object.

    hr = pIRowset->QueryInterface(IID_IColumnsInfo,

                                 (void **)&pIColumnsInfo);

    if(FAILED(hr))

    {

        cout << "Failed to get IColumnsInfo interface.\n";

    } //end if

  

    //Retrieve the column information.

    pIColumnsInfo->GetColumnInfo(&lNumCols,

                                 &pDBColumnInfo,

                                 &pStringsBuffer);

  

    //Free the column information interface.

    pIColumnsInfo->Release();

  

    //Create a DBBINDING array.

    pBindings = new DBBINDING[lNumCols];

  

    //Using the ColumnInfo structure, fill out the pBindings array.

    for(j=0; j<lNumCols; j++) {

        pBindings[j].iOrdinal = j+1;

        pBindings[j].obValue = ConsumerBufColOffset;

        pBindings[j].pTypeInfo = NULL;

        pBindings[j].pObject = NULL;

        pBindings[j].pBindExt = NULL;

        pBindings[j].dwPart = DBPART_VALUE;

        pBindings[j].dwMemOwner = DBMEMOWNER_CLIENTOWNED;

        pBindings[j].eParamIO = DBPARAMIO_NOTPARAM;

        pBindings[j].cbMaxLen = pDBColumnInfo[j].ulColumnSize;

        pBindings[j].dwFlags = 0;

        pBindings[j].wType = pDBColumnInfo[j].wType;

        pBindings[j].bPrecision = pDBColumnInfo[j].bPrecision;

        pBindings[j].bScale = pDBColumnInfo[j].bScale;

        

        //Compute the next buffer offset.

        ConsumerBufColOffset = ConsumerBufColOffset +

                               pDBColumnInfo[j].ulColumnSize;

    };

    //Get the IAccessor interface.

    hr = pIRowset->QueryInterface(IID_IAccessor, (void **) &pIAccessor);

    if(FAILED(hr))

    {

        cout << "Failed to obtain IAccessor interface.\n";

    }

//Create an accessor from the set of bindings (pBindings).

    pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,

                                lNumCols,

                                pBindings,

                                0,

                                &hAccessor,

                                NULL);

                                               

    //Print column names.

    for(j=0; j<lNumCols; j++) {

        printf("%-40S", pDBColumnInfo[j].pwszName);

    };

    //Get a set of 10 rows.

    pIRowset->GetNextRows(

                        NULL,

                        0,

                        10,

                        &lNumRowsRetrieved,

                        &pRows);

  

    //Allocate space for the row buffer.

    pBuffer = new BYTE[ConsumerBufColOffset];

  

    //Display the rows.

    while(lNumRowsRetrieved > 0) {

        //For each row, print the column data.

        for(j=0; j<lNumRowsRetrieved; j++) {

            //Clear the buffer.

            memset(pBuffer, 0, ConsumerBufColOffset);

            //Get the row data values.

            pIRowset->GetData(hRows[j], hAccessor, pBuffer);

            //Print title and price values.

            printf("%-40s%f\n", &pBuffer[pBindings[0].obValue],

                                (FLOAT) pBuffer[pBindings[0].obValue]);

        

        }; //for.

  

        //Release the rows retrieved.

        pIRowset->ReleaseRows(lNumRowsRetrieved,

                              hRows,

                              NULL,

                              NULL,

                              NULL);

        //Get the next set of 10 rows.

        pIRowset->GetNextRows(NULL,

                              0,

                              10,

                              &lNumRowsRetrieved,

                              &pRows);

    };  //while lNumRowsRetrieved > 0.

  

    //Free up all allocated memory.

    delete [] pBuffer;

    pIAccessor->ReleaseAccessor(hAccessor, NULL);

    pIAccessor->Release();

    delete [] pBindings;

} //ProcessResultSet.

  

  


(c) 1988-98 Microsoft Corporation. All Rights Reserved.