此頁沒有內(nèi)容條目
內(nèi)容

ADO 教程 (VC++)

本教程以新版 Microsoft Visual C++ Extensions 為特征。VC++ Extensions 刪除了對繁瑣的 VARIANT 數(shù)據(jù)類型的使用。

本教程還使用了 #import 偽指令,它將 ADO Typelib 轉(zhuǎn)換到頭文件中,這個(gè)頭文件使一些 ADO 的功能在使用和外觀上類似 Microsoft Visual Basic 中相應(yīng)的用法。

注意   在該范例中發(fā)布和使用的綁定宏已經(jīng)過更改,不再與原始文檔相同。有關(guān)當(dāng)前宏定義的詳細(xì)信息,請參閱頭文件 icrsint.h。

#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("ADODB.Connection.1.5");

      _RecordsetPtr pRs("ADODB.Recordset.1.5");

      CCustomRs rs;

// 步驟 1 — 打開連接

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

// 步驟 2 — 創(chuàng)建命令

// 步驟 3 — 執(zhí)行命令

      pRs->Open("select * from authors",

         _variant_t(pConn),

         adOpenDynamic, adLockOptimistic, adCmdText);

      if (FAILED(hr = pRs->QueryInterface(__uuidof(IADORecordBinding),

            (LPVOID*)&picRs)))

         _com_issue_error(hr);

      if (FAILED(hr = picRs->BindToRecordset(&rs)))

         _com_issue_error(hr);

// 步驟 4 — 操作數(shù)據(jù)

      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;

// 步驟 5 — 更新數(shù)據(jù)

      pConn->BeginTrans();

      try

         {

         pRs->UpdateBatch(adAffectAll);

         // 步驟 6-A — 結(jié)束更新

         pConn->CommitTrans();

         }

      catch (_com_error)

         {

         // 步驟 6-B  — 結(jié)束更新

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

   }

VC++ 教程到此結(jié)束。