Export (0) Print
Expand All
Expand Minimize

GetRows Method Example (VC++)

This example uses the GetRows method to retrieve a specified number of rows from a Recordset and to fill an array with the resulting data. The GetRows method will return less than the desired number of rows in two cases: either if EOF has been reached, or if GetRows tried to retrieve a record that was deleted by another user. The function returns False only if the second case occurs. The GetRowsOK function is required for this procedure to run.

// BeginGetRowsCpp.cpp
// compile with: /EHsc
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")

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

// Function Declarations
inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); };
void GetRowsX();
bool GetRowsOK(_RecordsetPtr pRstTemp, int intNumber, _variant_t& avarData);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

int main() {
   if (FAILED(::CoInitialize(NULL)))
      return -1;

   GetRowsX();
   ::CoUninitialize();
}

void GetRowsX() {
   HRESULT hr = S_OK;

   // Define string variables.
   _bstr_t strCnn("Provider='sqloledb'; Data Source='My_Data_Source'; Initial Catalog='pubs'; Integrated Security='SSPI';");

   // Define ADO object pointers, initialize pointers on define. 
   // These are in the ADODB::  namespace.
   _RecordsetPtr pRstEmployees = NULL;

   try  {
      // Open recordset with names and hire dates from employee table.
      TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));

      pRstEmployees->Open("SELECT fName, lName, hire_date "
         "FROM Employee ORDER BY lName",strCnn, adOpenStatic, adLockReadOnly, adCmdText);

      while (true) {   // continuous loop
         int intLines = 0;

         // Get user input for number of rows.
         printf("Enter number of rows to retrieve (0 to exit): ");
         int intRows;
         scanf_s("%d", &intRows);

         if (intRows <= 0)
            break;

         // If GetRowsOK is successful, print the results,
         // noting if the end of the file was reached.
         _variant_t avarRecords;

         if (GetRowsOK(pRstEmployees, intRows, avarRecords)) {
            long lUbound;
            HRESULT hr = SafeArrayGetUBound(avarRecords.parray, 2, &lUbound);

            if (hr == 0) {
               if (intRows > lUbound + 1) {
                  printf("\n(Not enough records in Recordset to retrieve %d rows)\n", intRows);
               }
            }
            printf("%d record(s) found.\n", lUbound + 1);

            // Print the retrieved data.
            for (int intRecords = 0 ; intRecords < lUbound+1 ; intRecords++) {
               long rgIndices[2];
               rgIndices[0] = 0; 
               rgIndices[1] = intRecords;
               _variant_t result;
               result.vt = VT_BSTR;

               hr = SafeArrayGetElement(avarRecords.parray, rgIndices, &result);

               if (hr == 0)
                  printf("%s ",(LPCSTR)(_bstr_t)result);
               
               rgIndices[0] = 1;

               hr = SafeArrayGetElement(avarRecords.parray, rgIndices, &result);

               if (hr == 0)
                  printf("%s, ",(LPCSTR)(_bstr_t)result);

               rgIndices[0] = 2;

               hr = SafeArrayGetElement(avarRecords.parray, rgIndices, &result);

               if (hr == 0)
                  printf("%s\n", (LPCSTR)(_bstr_t)result);

               intLines ++;

               if (intLines % 10 == 0) {
                  printf("\nPress any key to continue...");
                  _getch();
                  intLines = 0;
                  system("cls");
               }
            }
            printf("\n");
         }
         else {
            // Assume GetRows error caused by another user's data changes, 
            // use Requery to refresh the Recordset and start over.
            printf("GetRows failed--retry?\n");
            char chKey;
            do {
               chKey = _getch();
            } while (toupper(chKey) != 'Y'  && toupper(chKey) != 'N');

            if (toupper(chKey) == 'Y')
               pRstEmployees->Requery(adOptionUnspecified);
            else {
               printf("GetRows failed!\n");
               break;
            }
         }

         // Because using GetRows leaves the current record pointer at the last record 
         // accessed, move the pointer back to the beginning of the Recordset before 
         // looping back for another search.
         pRstEmployees->MoveFirst();
      }
   }  
   catch(_com_error &e) {
      // Notify the user of errors if any.
      // Pass a connection pointer accessed from the Recordset.
      _variant_t vtConnect = pRstEmployees->GetActiveConnection();

      // GetActiveConnection returns connect string if connection
      // is not open, else returns Connection object.
      switch(vtConnect.vt) {
         case VT_BSTR:
            PrintComError(e);
            break;
         case VT_DISPATCH:
            PrintProviderError(vtConnect);
            break;
         default:
            printf("Errors occured.");
            break;
      }
   }

   // Clean up objects before exit.
   if (pRstEmployees)
      if (pRstEmployees->State == adStateOpen)
         pRstEmployees->Close();
}

bool GetRowsOK(_RecordsetPtr pRstTemp,int intNumber, _variant_t& avarData) {
   // Store results of GetRows method in array.
   avarData = pRstTemp->GetRows(intNumber);

   // Return False only if fewer than the desired number of rows were returned, 
   // but not because the end of the Recordset was reached.
   long lUbound;
   HRESULT hr = SafeArrayGetUBound(avarData.parray, 2, &lUbound);   
   if (hr == 0) {
      if ((intNumber > lUbound + 1) && (!(pRstTemp->EndOfFile)))
         return false;
      else
         return true;   
   }
   else  {
      printf ("\nUnable to Get the Array's Upper Bound\n");
      return false;
   }
}

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);
      }
   }
}

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);
}

Input

2
0

2 record(s) found.
Paolo Accorti, 8/27/1992
Pedro Afonso, 12/24/1990
Show:
© 2015 Microsoft