Find Method Example (VC++)

Microsoft ActiveX Data Objects (ADO)

Find Method Example (VC++)

This example uses the Recordset object's Find method to locate and count the number of business titles in the Pubs database. The example assumes the underlying provider does not support similar functionality.

#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include "FindX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void FindX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////

void main()
{
    If(FAILED(::CoInitialize(NULL)))
        return;

    FindX();

    //Wait here for the user to see the output.
    printf("Press any key to continue...");
    getch();
    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//             FindX Function                           //
//                                                      //
//////////////////////////////////////////////////////////

void FindX(void) 
{
    HRESULT    hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr    pConnection  = NULL;
    _RecordsetPtr     pRstTitles   = NULL;
    IADORecordBinding   *picRs     = NULL;  //Interface Pointer declared.
    CTitlesRs titlers;                      //C++ class object

    _bstr_t strCnn("Provider=sqloledb;Data Source=srv;"
            "Initial Catalog=Pubs;User Id=sa;Password=;");

    try
    {
        // Open connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open (strCnn, "", "", NULL);

        // Open Titles Table
        TESTHR(pRstTitles.CreateInstance(__uuidof(Recordset)));
        
        pRstTitles->Open("SELECT title_id FROM Titles",
            _variant_t((IDispatch *)pConnection), 
            adOpenStatic, adLockReadOnly, adCmdText);

        // The default parameters are sufficient to search forward
        // through a Recordset.

        pRstTitles->Find ("title_id LIKE 'BU%'",0,adSearchForward,"");

        //Open an IADORecordBinding interface pointer which 
        //we'll use for Binding Recordset to a class    
        TESTHR(pRstTitles->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here    
        TESTHR(picRs->BindToRecordset(&titlers));

        // Skip the current record to avoid finding the same 
        // row repeatedly. The bookmark is redundant because Find 
        // searches from the current position.
        int count = 0;

        //Continue if last find succeeded.
        while (!(pRstTitles->EndOfFile)) 
        {
            printf("Title ID: %s\n",titlers.lt_titleidStatus == adFldOK ?
                titlers.m_szt_titleid : "<NULL>");
            count++;                       //Count the last title found.

            _variant_t mark = pRstTitles->Bookmark;  //Note current pos.
            pRstTitles->Find("title_id LIKE 'BU%'", 1, adSearchForward, 
                mark);
        }

        //Release IADORecordset Interface
        if (picRs)
            picRs->Release();

        // Clean up objects before exit.
        pRstTitles->Close();
        pConnection->Close();
        printf("The number of business titles is %d\n",count);

   }

   catch(_com_error &e)
   {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
       PrintProviderError(pConnection);
       PrintComError(e);
   }
}

//////////////////////////////////////////////////////////
//                                                      //
//       PrintProviderError Function                    //
//                                                      //
//////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number, 
                (LPCSTR) pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//       PrintComError Function                         //
//                                                      //
//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}

FindX.h

#include "icrsint.h"

//This Class extracts only titleId from Titles table.
class CTitlesRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CTitlesRs)

    // Column title_id is the 1st field in the recordset 
    // from Titles table.
    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_szt_titleid, 
         sizeof(m_szt_titleid), lt_titleidStatus, FALSE)

END_ADO_BINDING()

public:
   CHAR   m_szt_titleid[150];
   ULONG   lt_titleidStatus;
};