How to obtain FAST_FORWARD cursor

To obtain a forward-only, read-only cursor, set the rowset properties, DBPROP_SERVERCURSOR, DBPROP_OTHERINSERT, DBPROP_OTHERUPDATEDELETE, DBPROP_OWNINSERT, DBPROP_OWNUPDATEDELETE to VARIANT_TRUE.

To obtain FAST_FORWARD cursor

  1. Establish a connection to the data source.
  2. Set the rowset properties, DBPROP_SERVERCURSOR, DBPROP_OTHERINSERT, DBPROP_OTHERUPDATEDELETE, DBPROP_OWNINSERT, DBPROP_OWNUPDATEDELETE should be set to VARIANT_TRUE
  3. Execute the command.

The following example shows how to set the rowset properties to obtain a FAST_FORWARD cursor. After the properties are set, a SELECT statement is executed to find the first and last names of authors in the pubs database.

#define INITGUID

#define DBINITCONSTANTS

  

#include <windows.h>

#include <stdio.h>

#include <oledb.h>

#include <sqloledb.h>

#include <oledberr.h>

  

IDBInitialize* pIDBInitialize = NULL;

ICommandText*  pICommandText  = NULL;

  

// Connect to the server and create a command object.

void InitializeAndConnect();

  

// Set the properties to get a FAST_FORWARD cursor.

void SetRowsetProperties();

  

// This function executes a command and displays the results.

void ExecuteAndDisplay();

  

// Clean up the memory.

void Cleanup();

  

void main()

{

    // Initialize.

    InitializeAndConnect();

  

    // Set the row properties to FAST_FORWARD cursor.

    SetRowsetProperties();

  

    // Execute a command and display the results.

    ExecuteAndDisplay();

  

    // Cleanup.

    Cleanup();

}

  

void InitializeAndConnect()

{

    HRESULT              hr                   = S_OK;

    IDBProperties*       pIDBProperties       = NULL;

    IDBCreateSession*    pIDBCreateSession    = NULL;

    IDBCreateCommand*    pIDBCreateCommand    = NULL;

    DBPROPSET            dbPropSet;

    DBPROP               dbProp[4];

  

    // Initialize OLE

    if( FAILED( hr = OleInitialize( NULL ) ) )

    {

        // Handle errors here.

    }

  

    // Create an instance of Microsoft OLE DB Provider for SQL Server.

    if( FAILED( hr = CoCreateInstance(   

                                CLSID_SQLOLEDB,

                                NULL,

                                CLSCTX_INPROC_SERVER,

                                IID_IDBProperties,

                                (void **) &pIDBProperties ) ) )

    {

        // Handle errors here.

    }

  

    // Set up the connection properties.

    dbProp[0].dwPropertyID      = DBPROP_INIT_DATASOURCE;

    dbProp[0].dwOptions         = DBPROPOPTIONS_REQUIRED;

    dbProp[0].colid             = DB_NULLID;

    V_VT(&(dbProp[0].vValue))   = VT_BSTR;

    V_BSTR(&(dbProp[0].vValue)) = SysAllocString( L"server " );

  

    dbProp[1].dwPropertyID      = DBPROP_AUTH_USERID;

    dbProp[1].dwOptions         = DBPROPOPTIONS_REQUIRED;

    dbProp[1].colid             = DB_NULLID;

    V_VT(&(dbProp[1].vValue))   = VT_BSTR;

    V_BSTR(&(dbProp[1].vValue)) = SysAllocString( L"login" );

  

    dbProp[2].dwPropertyID      = DBPROP_AUTH_PASSWORD;

    dbProp[2].dwOptions         = DBPROPOPTIONS_REQUIRED;

    dbProp[2].colid             = DB_NULLID;

    V_VT(&(dbProp[2].vValue))   = VT_BSTR;

    V_BSTR(&(dbProp[2].vValue)) = SysAllocString( L"" );

  

    dbProp[3].dwPropertyID      = DBPROP_INIT_CATALOG;

    dbProp[3].dwOptions         = DBPROPOPTIONS_REQUIRED;

    dbProp[3].colid             = DB_NULLID;

    V_VT(&(dbProp[3].vValue))   = VT_BSTR;

    V_BSTR(&(dbProp[3].vValue)) = SysAllocString( L"pubs" );

  

    dbPropSet.rgProperties      = dbProp;

    dbPropSet.cProperties       = 4;

    dbPropSet.guidPropertySet   = DBPROPSET_DBINIT;

  

    if( FAILED( hr = pIDBProperties->SetProperties(

                                        1,

                                        &dbPropSet )))

    {

        // Handle errors here.

    }

  

    SysFreeString( V_BSTR(&(dbProp[0].vValue)) );

    SysFreeString( V_BSTR(&(dbProp[1].vValue)) );

    SysFreeString( V_BSTR(&(dbProp[2].vValue)) );

    SysFreeString( V_BSTR(&(dbProp[3].vValue)) );

  

    // Get an IDBInitialize interface.

    if( FAILED( hr = pIDBProperties->QueryInterface(

                                   IID_IDBInitialize,

                                   (void **) &pIDBInitialize )))

    {

        // Handle errors here.

    }

  

    // Call Initialize.

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

    {

        // Handle errors here.

    }

  

    // Get a IDBCreateSession interface.

    if( FAILED( hr = pIDBInitialize->QueryInterface(

                                IID_IDBCreateSession,

                                (void **) &pIDBCreateSession )))

    {

        // Handle errors here.

    }

  

    // Create a session

    if( FAILED( hr = pIDBCreateSession->CreateSession(

                                 NULL,

                                 IID_IDBCreateCommand,

                                 (IUnknown **) &pIDBCreateCommand)))

    {

        // Handle errors here.

    }

  

    // Create a command.

    if( FAILED( hr = pIDBCreateCommand->CreateCommand(

                                     NULL,

                                     IID_ICommandText,

                                     (IUnknown **) &pICommandText)))

    {

        // Handle errors here.

    }

  

    // Release all the objects not needed anymore.

    pIDBProperties->Release();

    pIDBCreateSession->Release();

    pIDBCreateCommand->Release();

}

  

void SetRowsetProperties()

{

    HRESULT              hr                    = S_OK;

    ICommandProperties*  pICommandProperties   = NULL;

    DBPROPSET            dbPropSet;

    DBPROP               dbProp[5];

  

    // Get an ICommandProperties object.

    if( FAILED( hr = pICommandText->QueryInterface(

                        IID_ICommandProperties,

                        (void **) &pICommandProperties )))

    {

        // Handle errors here.

    }

  

    // Set up the properties to get a FAST_FORWARD cursor.

    dbProp[0].dwPropertyID       = DBPROP_SERVERCURSOR;

    dbProp[0].dwOptions          = DBPROPOPTIONS_REQUIRED;

    dbProp[0].colid              = DB_NULLID;

    V_VT(&(dbProp[0].vValue))    = VT_BOOL;

    V_BOOL(&(dbProp[0].vValue))  = VARIANT_TRUE;

  

    dbProp[1].dwPropertyID       = DBPROP_OTHERINSERT;

    dbProp[1].dwOptions          = DBPROPOPTIONS_REQUIRED;

    dbProp[1].colid              = DB_NULLID;

    V_VT(&(dbProp[1].vValue))    = VT_BOOL;

    V_BOOL(&(dbProp[1].vValue))  = VARIANT_TRUE;

  

    dbProp[2].dwPropertyID       = DBPROP_OTHERUPDATEDELETE;

    dbProp[2].dwOptions          = DBPROPOPTIONS_REQUIRED;

    dbProp[2].colid              = DB_NULLID;

    V_VT(&(dbProp[2].vValue))    = VT_BOOL;

    V_BOOL(&(dbProp[2].vValue))  = VARIANT_TRUE;

  

    dbProp[3].dwPropertyID       = DBPROP_OWNINSERT;

    dbProp[3].dwOptions          = DBPROPOPTIONS_REQUIRED;

    dbProp[3].colid              = DB_NULLID;

    V_VT(&(dbProp[3].vValue))    = VT_BOOL;

    V_BOOL(&(dbProp[3].vValue))  = VARIANT_TRUE;

  

    dbProp[4].dwPropertyID       = DBPROP_OWNUPDATEDELETE;

    dbProp[4].dwOptions          = DBPROPOPTIONS_REQUIRED;

    dbProp[4].colid              = DB_NULLID;

    V_VT(&(dbProp[4].vValue))    = VT_BOOL;

    V_BOOL(&(dbProp[4].vValue))  = VARIANT_TRUE;

  

    dbPropSet.rgProperties       = dbProp;

    dbPropSet.cProperties        = 5;

    dbPropSet.guidPropertySet    = DBPROPSET_ROWSET;

  

    if( FAILED( hr = pICommandProperties->SetProperties(

                                            1,

                                            &dbPropSet)))

    {

        // Handle errors here.

    }

  

    // Release the ICommandProperties object.

    pICommandProperties->Release();

}

  

void ExecuteAndDisplay()

{

    HRESULT             hr                  = S_OK;

    IRowset*            pIRowset            = NULL;

    IAccessor*          pIAccessor          = NULL;

    BYTE*               pData               = NULL;

    ULONG               cRowsObtained       = 0;

    ULONG               cCount              = 0;

    HROW*               pRows               = new HROW[10];

    HACCESSOR           hAccessor;

    DBBINDING           Bind[2];

    

    // Set the command text.

    if( FAILED( hr = pICommandText->SetCommandText(

                        DBGUID_SQL,

                        L"select au_lname, au_fname from authors")))

    {

        // Handle errors here.

    }

  

    // Execute the command.

    if( FAILED( hr = pICommandText->Execute(

                                          NULL,

                                          IID_IRowset,

                                          NULL,

                                          NULL,

                                          (IUnknown **) &pIRowset )))

    {

        // Handle errors here.

    }

  

    // Set up the binding structure for au_lname (varchar(40)).

    Bind[0].dwPart      = DBPART_VALUE;

    Bind[0].eParamIO    = DBPARAMIO_NOTPARAM;

    Bind[0].iOrdinal    = 1;

    Bind[0].pTypeInfo   = NULL;

    Bind[0].pObject     = NULL;

    Bind[0].pBindExt    = NULL;

    Bind[0].dwFlags     = 0;

    Bind[0].dwMemOwner  = DBMEMOWNER_CLIENTOWNED;

    Bind[0].obLength    = 0;

    Bind[0].obStatus    = 0;

    Bind[0].obValue     = 0;

    Bind[0].cbMaxLen    = 40;

    Bind[0].wType       = DBTYPE_STR;

    Bind[0].bPrecision  = 0;

    Bind[0].bScale      = 0;

  

    // Set up the binding structure for au_fname (varchar(20)).

    Bind[1].dwPart      = DBPART_VALUE;

    Bind[1].eParamIO    = DBPARAMIO_NOTPARAM;

    Bind[1].iOrdinal    = 2;

    Bind[1].pTypeInfo   = NULL;

    Bind[1].pObject     = NULL;

    Bind[1].pBindExt    = NULL;

    Bind[1].dwFlags     = 0;

    Bind[1].dwMemOwner  = DBMEMOWNER_CLIENTOWNED;

    Bind[1].obLength    = 0;

    Bind[1].obStatus    = 0;

    Bind[1].obValue     = 50;

    Bind[1].cbMaxLen    = 20;

    Bind[1].wType       = DBTYPE_STR;

    Bind[1].bPrecision  = 0;

    Bind[1].bScale      = 0;

  

    // Get an IAccessor interface.

    if( FAILED( hr = pIRowset->QueryInterface(

                                IID_IAccessor,

                                (void **) &pIAccessor)))

    {

        // Handle errors here.

    }

  

    // Create an accessor.

    if( FAILED( hr = pIAccessor->CreateAccessor(

                                DBACCESSOR_ROWDATA,

                                2,

                                Bind,

                                0,

                                &hAccessor,

                                NULL)))

    {

        // Handle errors here.

    }

  

    // Allocate memory for the data.

    pData = new BYTE[100];

  

    // Loop through all of the rows.

    while( TRUE )

    {

        if( FAILED( hr = pIRowset->GetNextRows(

                                    NULL,

                                    0,

                                    10,

                                    &cRowsObtained,

                                    &pRows ) ) )

        {

            // Handle errors here.

        }

  

        // Make sure some rows were obtained.

        if( cRowsObtained == 0 )

        {

            break;

        }

  

        // Get the data for the each of the rows.

        for( cCount = 0; cCount < cRowsObtained; cCount++ )

        {

            // Get the row data needed.

            if( FAILED( hr = pIRowset->GetData(

                                        pRows[cCount],

                                        hAccessor,

                                        pData )))

            {

                // Handle errors here.

            }

  

            // Display row data.

            printf( "%s, %s\n", pData, ( pData + 50 ));

        }

  

        // Release the rows.

        if( FAILED( hr = pIRowset->ReleaseRows(

                                    cRowsObtained,

                                    pRows,

                                    NULL,

                                    NULL,

                                    NULL )))

        {

            // Handle errors here.

        }

    }

  

    // Free the memory allocated for the data.

    delete [] pData;

  

    // Release the HACCESSOR.

    if( FAILED( hr = pIAccessor->ReleaseAccessor(

                                        hAccessor,

                                        NULL )))

    {

        // Handle errors here.

    }

  

    // Release the IAccessor object.

    pIAccessor->Release();

  

    // Release the rowset.

    pIRowset->Release();

}

  

void Cleanup()

{

    HRESULT  hr = S_OK;

  

    // Release the ICommandText object.

    pICommandText->Release();

  

    // Uninitialize the IDBInitialize object.

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

    {

        // Handle errors here.

    }

  

    // Release the IDBInitialize object.

    pIDBInitialize->Release();

  

    // Uninitialize OLE.

    OleUninitialize();

}

  


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