Microsoft KB Archive/231351

From BetaArchive Wiki
Knowledge Base


DOC: ADO VC Tutorial in MSDN Has Compile/Run-Time Errors

Article ID: 231351

Article Last Modified on 10/17/2003



APPLIES TO

  • Microsoft Data Access Components Software Development Kit 2.0
  • Microsoft Data Access Components Software Development Kit 2.1
  • Microsoft ActiveX Data Objects 2.0
  • Microsoft ActiveX Data Objects 2.1



This article was previously published under Q231351

SUMMARY

The ADO Visual C++ Tutorial in MSDN has problems in the code that can cause one or more compilation or run-time errors.

To get to this tutorial, do the following:

  1. Start MSDN, click the Contents tab.
  2. Navigate as follows: Platform SDK, Data Access Service, Microsoft Data Access 2.1 SDK, Microsoft ActiveX Data Objects (ADO), Microsoft ADO Programmer's Reference.
  3. From the Microsoft ADO Programmer's Reference, navigate as follows: Learning ADO, ADO and RDS Tutorials, ADO Tutorial, ADO Tutorial (VC++).

One error that the user may get at run time is the following:

Error Code = 800a0bb9 Code meaning = Unknown error 0x800A0BB9 Source = ADODB.Recordset Description = The application is using arguments that are of the wrong type, are out of acceptable range, or are in conflict with one another.

The above error is caused by the wrong syntax in the Open method on the recordset in following line:

 pRs->Open("select * from authors", 
         _variant_t (pConn),
         adOpenDynamic, adLockOptimistic, adCmdText);
                


Another error that the user may get at run time is the following:

Error Code = 800a0cc1 Code meaning = Unknown error 0x800A0CC1 Source = ADODB.Properties Description = ADO could not find the object in the collection corresponding to the name or ordinal reference requested by the application.


The above error was caused by not using client-side cursors for an "Optimize" property in the following line of code:

 pRs->Fields->GetItem("au_lname")->Properties->GetItem("Optimize")->Value = true; 
                

MORE INFORMATION

Following is the code that corrects the above mentioned errors. Just replace the code from the sample with the following code:

// START ADO VC++ TUTORIAL
#define INITGUID
#import "c:\Program Files\Common Files\System\ADO\msado15.dll"    no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>
#include <icrsint.h>

void dump_com_error(_com_error &e)
   {
   printf("Error\n");
   printf("\a\tCode = %08lx\n", e.Error());
   printf("\a\tCode meaning = %s", e.ErrorMessage());
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());
   printf("\a\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription);
   }

class CCustomRs : 
   public CADORecordBinding
{
BEGIN_ADO_BINDING(CCustomRs)
   ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_szau_lname, 
         sizeof(m_szau_lname), lau_lnameStatus, false)
   ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szau_fname, 
         sizeof(m_szau_fname), lau_fnameStatus, false)
   ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_szphone,    
         sizeof(m_szphone),    lphoneStatus,    true)
END_ADO_BINDING()

public:
   CHAR   m_szau_lname[41];
   ULONG   lau_lnameStatus;
   CHAR   m_szau_fname[41];
   ULONG   lau_fnameStatus;
   CHAR   m_szphone[12];
   ULONG   lphoneStatus;
};

VOID   main()
   {
   HRESULT            hr;
   IADORecordBinding   *picRs = NULL;
   
   ::CoInitialize(NULL);

   try 
      {
      _ConnectionPtr pConn(__uuidof(Connection)); // FIX #1: DON'T USE PROGID!
      _RecordsetPtr pRs(__uuidof(Recordset));     // FIX #2: DON'T USE PROGID!
      CCustomRs rs;

// Step 1: Open a connection

      pConn->Open("dsn=pubs;", "sa", "", adConnectUnspecified);

// Step 2: Create a command
// Step 3: Execute the command
        
      pRs->CursorLocation = adUseClient; // FIX #3: NEED CLIENT CURSOR FOR BATCH UPDATES!
      pRs->Open("select * from authors",
         _variant_t((IDispatch*)pConn), // FIX #4:  MUST CAST SMART POINTER TO LPDISPATCH!
         adOpenDynamic, 
         adLockBatchOptimistic,          // FIX #5: MUST USE adLockBatchOptimistic
         adCmdText);
      
      if (FAILED(hr = pRs->QueryInterface(__uuidof(IADORecordBinding), 
            (LPVOID*)&picRs)))
         _com_issue_error(hr);
      
      if (FAILED(hr = picRs->BindToRecordset(&rs)))
         _com_issue_error(hr);

// Step 4: Manipulate the data

      pRs->Fields->Item["au_lname"]->Properties->Item["Optimize"]->Value = true;  // FIX #6: USE PROPER SMART POINTER SYNTAX.
      //pRs->Fields->GetItem("au_lname")->Properties->GetItem("Optimize")->Value = true; 
      pRs->Sort = "au_lname ASC";
      pRs->Filter = "phone LIKE '415 5*'";

      pRs->MoveFirst();
      while (VARIANT_FALSE == pRs->EndOfFile)
         {
         printf("\a\tName: %s\t %s\tPhone: %s\n",  
            (rs.lau_fnameStatus == adFldOK ? rs.m_szau_fname : ""), 
            (rs.lau_lnameStatus == adFldOK ? rs.m_szau_lname : ""),
            (rs.lphoneStatus == adFldOK ? rs.m_szphone   : ""));

         if (rs.lphoneStatus == adFldOK)
            memcpy(rs.m_szphone, "777", 3);
            
         if (FAILED(hr = picRs->Update(&rs)))
            _com_issue_error(hr);

      // Change the current row of the Recordset. 
      // Recordset data for the new current row will automatically be 
      // extracted and placed in the CCustomRs C++ instance variables.
   
         pRs->MoveNext();
         }
      pRs->Filter = (long) adFilterNone;

// Step 5: Update the data

      pConn->BeginTrans();
      try 
         {
         pRs->UpdateBatch(adAffectAll);

         // Step 6, part A: Conclude the update 
         pConn->CommitTrans();
         }

      catch (_com_error)
         {
         // Step 6, part B: Conclude the update 
         pRs->Filter = (long) adFilterConflictingRecords;
         pRs->MoveFirst();
         while (VARIANT_FALSE == pRs->EndOfFile)
            {
            printf("\a\tConflict: Name = %s\t %s\n", 
               (rs.lau_fnameStatus == adFldOK ? rs.m_szau_fname : ""), 
               (rs.lau_lnameStatus == adFldOK ? rs.m_szau_lname : ""));
            pRs->MoveNext();
            }
         pConn->RollbackTrans();
         }
      }

   catch (_com_error &e)
      {
      dump_com_error(e);
      }

   CoUninitialize();
   }
// END ADO VC++ TUTORIAL
                


Microsoft has confirmed that this is a bug in ADO VC Tutorial in MSDN version April 99 for Winodws 95/98/NT4.0.

REFERENCES

For additional information about using ADO in Visual C++, please see the following articles in the Microsoft Knowledge Base:

220152 Sample: ADOVC1 Simple ADO/VC++ Application


185033 FILE: Adoacc.exe Demonstrates Using ADO with Access 97



Additional query words: problem problematic MDAC

Keywords: kbdatabase kbdocfix kbdocerr KB231351