CADORecordBinding

1.定义:#import <icrsint.h>

2.微软定义了一些宏用于将变量绑定到记录集上。

3.BEGIN_ADO_BINDING(myClass)

     ......

   End_ADO_BINDING()

4.ADO_FIXED_LENGTH_ENTRY()|ADO_FIXED_LENGTH_ENTRY2()

ADO_NUMBERIC_ENTRY()|ADO_NUMBERIC_ENTRY2()

ADO_VARIABLE_LENGTH_ENTRY()|ADO_VARIABLE_LENGTH_ENTRY2()

 

 

 

 

 

 

下面是转载1:http://support.microsoft.com/kb/231351/zh-cn,特此声明并感谢。

// 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

 

 

下面是转载2:http://hi.baidu.com/embrace_you/blog/item/a8f13a3f2be366ca7d1e719e.html

特此声明并感谢。

 

当我们使用Visual C++进行ADO编程时,一项颇为头疼的工作就是对VARIANT字段类型的处理。通常做法是,先把VARIANT类型转换为形式上较为类似的C++类型,然后再把转换后的数据存放在一个类(class)或结构(structure)中。即便如此,对VARIANT数据类型的处理在一定程度上也影响到了程序的性能。

  ADO为我们提供了一个接口,该接口使我们可以把数据直接读取到本地,从而绕开对于复杂的VARIANT数据类型的处理。同时,ADO还定义了一组预处理宏,用来简化接口的使用。用好这一工具,将会使我们的编程工作将变得轻松和高效。

  一般情况下,我们从ADO获得Recordset数据集,然后定义一个C/C++结构类型,再把Recordset中的记录绑定到结构成员变量中。当遇到VARIANT类型时,情况变得复杂,你必须解决如何把VARIANT数据类型(数据库)转换到C/C++数据类型(本地)的问题。Visual C++ Extensions for ADO(为叙述方便,以下简称ADOExt)的目标就是使这一切变得简单。

  【IADORecordBinding 接口简介

  ADOExt 把RecordSet记录集中的字段绑定到C/C++变量中。一旦该Recordset当前行的数据发生改变,数据将被立即拷贝到绑定的C/C++变量中。根据需要,数据将被转换到指定的C/C++数据类型。

  IADORecordBinding 接口的 BindToRecordset 成员方法用来实现数据库字段到本地C/C++变量之间的绑定。如果要为Recordset新增一条记录,可以使用AddNew方法。Update方法则用来把绑定的C/C++变量数据更新和升级到数据库中。

  IADORecordBinding 接口的实现不用我们操心,Recordset对象悄悄的在幕后完成这一切。

  【绑定单元(Binding Entries)简介

  ADOExt 把Recordset对象的字段类型映射到本地的C/C++变量中,我们把这种从一个数据库字段映射到一个C/C++变量之间的过程定义称为一个绑定单元(Binding Entries)。绑定由宏来完成,可以绑定的类型包括数值型、定长、以及可变长度的数据。绑定的基本流程是:定义派生自CADORecordBinding(CADORecordBinding 类本身其实也是一组宏定义)的类,在类中使用特定的宏来实现数据绑定。然后,在类中声明相应的C/C++变量。

  ADO 在内部把宏定义中的参数映射到一个OLE DB DBBINDING类型的结构中,并且创建一个OLE DB 存取对象用来管理字段和变量之间的数据移动和格式转换。OLE DB 的数据定义包括三个部分:一个用来储存数据的缓冲区;一个用来标示数据存取状态,以及变量如何提取的状态位;以及数据的长度。

  【头文件包含

  要使用 Visual C++ 的ADOExt, 你需要在应用程序中包含下列头文件:

  #include

  【绑定Recordset 字段的过程

  ■创建一个派生自CADORecordsetBinding的类。

  ■在派生类中设定绑定单元并定义相应的C/C++变量。这些绑定单元被界定在 BEGIN_ADO_BINDING 和 END_ADO_BINDING 之间。不要想当然的在宏定义间放置逗号或者分号,这些工作会由宏在内部自动实现。

  ■为每一个要映射为C/C++变量的数据库字段指定一个绑定单元。根据需要从ADO_FIXED_LENGTH_ENTRY, ADO_NUMERIC_ENTRY, 或者 ADO_VARIABLE_LENGTH_ENTRY 这三个宏定义中选择一个,并填写上正确的参数。

  ■在你的引用程序中,创建一个该类的实例。从 Recordset 中获取 IADORecordBinding 接口。然后调用BindToRecordset方法实现数据绑定。

  【接口方法定义

  IADORecordBinding 接口有三个方法:BindToRecordset, AddNew, 以及 Update。这些方法有且只有一个指针类型的参数,该参数指向一个派生自CADORecordBinding的类实例。事实上,AddNew 和 Updage 方法 将分别调用 ADO 中的同名方法。

  语法:

  BindToRecordset 方法实现 Recordset 字段到 C/C++ 变量之间的绑定。

  BindToRecordset(CADORecordBinding *binding)

  AddNew 方法调用它的同名方法,ADO 中的 AddNew 方法,向 Recordset 中增加一条新的记录。

  AddNew(CADORecordBinding *binding)

  Update 方法调用它在ADO中的同名方法 Update, 完成对Recordset的数据更新。

  Update(CADORecordBinding *binding)
理解绑定单元中的宏

  绑定单元定义了Recordset字段和变量之间的联系。 宏BEGIN_ADO_BINDING(Class)(开始宏)和END_ADO_BINDING()(结束宏)界定了一组绑定单元。

  绑定单元中的宏提供了对于下列字段类型的支持:

  ■定长类型的数据。例如 adDate 或 adBoolean

  ■数值型数据。例如 adTinyInt, adInteger, 以及 adDouble

  ■变长类型的数据。例如 adChar, adVarChar 以及 adVarBinary

  所有的数值型数据,除了 adVarNumeric 类型之外,同时也都是定长类型的数据。

  不同的宏定义使用不同类型的参数,这样你就可以排除不感兴趣的绑定信息。

  ■开始数据绑定

  BEGIN_ADO_BINDING(Class)

  ■定长类型的数据

ADO_FIXED_LENGTH_ENTRY(Ordinal, DataType, Buffer, Status, Modify)
ADO_FIXED_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Modify)


  ■数值型数据

ADO_NUMERIC_ENTRY(Ordinal, DataType, Buffer, Precision, Scale, Status, Modify)
ADO_NUMERIC_ENTRY2(Ordinal, DataType, Buffer, Precision, Scale, Modify)


  ■可变长度类型的数据

ADO_VARIABLE_LENGTH_ENTRY(Ordinal, DataType, Buffer, Size, Status, Length, Modify)
ADO_VARIABLE_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Size, Status, Modify)
ADO_VARIABLE_LENGTH_ENTRY3(Ordinal, DataType, Buffer, Size, Length, Modify)
ADO_VARIABLE_LENGTH_ENTRY4(Ordinal, DataType, Buffer, Size, Modify)


  ■结束数据绑定

END_ADO_BINDING()


参数:描述
Class:绑定单元和C/C++变量定义所在的类。
Ordinal:序数类型,从1开始计数的Recordset字段序号,该字段对应于指定的C/C++变量。
DataType: 和ADO中的数据类型等价的C/C++数据类型。相应的Recordset字段在需要时将转换为该数据类型。
Buffer:用来存储Recordset字段的缓冲区名称。
Size:缓冲区的最大尺寸。
Status:状态位。指示缓冲区的内容的有效性,以及字段转换是否成功。其中有两个比较重要的值。一个是adFldOK, 表明转换是成功的;另一个是adFldNull, 表明字段值为NULL。更多的状态值,请参考MSDN
Modify:布尔类型。如果为TRUE, 表明ADO允许更新缓冲区中的数据。如果为FALSE,表明数据是只读的。
Precision:
数值类型的精度。
Scale:数值类型的小数位数。Number of decimal places in a numeric variable.
Length:
一个四字节的变量。用来包含缓冲区中数据的实际长度。


  【Visual C++ Extensions 例程

//引入msado15.dll文件,从而声明了ADO类型库
#import "c:/Program Files/Common Files/System/ADO/msado15.dll" no_namespace rename("EOF", "EndOfFile")

#include
#include file://在此处包含icrsint.h头文件

file://_COM_SMARTPTR_TYPEDEF 宏定义了一个_com_ptr_t类型的智能(smart)指针IADORecordBingingPtr
_COM_SMARTPTR_TYPEDEF(IADORecordBinding, __uuidof(IADORecordBinding));

file://定义一个测试函数
inline void TESTHR(HRESULT _hr) { if FAILED(_hr) _com_issue_error(_hr); }

file://定义一个派生自CADORecordBinding的类
class CCustomRs : public CADORecordBinding
{
file://开始进行数据类型绑定
BEGIN_ADO_BINDING(CCustomRs)
file://把Recordset的第2个adVarChar类型的字段绑定到C/C++变量m_ch_fname上
ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_ch_fname,
sizeof(m_ch_fname), m_ul_fnameStatus, false)
ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_ch_lname,
sizeof(m_ch_lname), m_ul_lnameStatus, false)
file://结束绑定
END_ADO_BINDING()

file://紧接着定义上述宏中用到的C/C++变量
public:
CHAR m_ch_fname[22];
CHAR m_ch_lname[32];
ULONG m_ul_fnameStatus;
ULONG m_ul_lnameStatus;
};

file://开始程序执行
void main(void)
{
::CoInitialize(NULL); file://初始化COM对象
try
{
file://typedef _com_ptr_t<_Recordset, __uuidof(_Recordset)> _RecordsetPtr:指向一个_Recordset的智能指针
_RecordsetPtr pRs("ADODB.Recordset");

file://定义一个CCustomRS: public CADORecordBinding类的实例
CCustomRs rs;

file://把IADORecordBindingPtr接口类型对象picRs指定到pRs对象,从而实现接口和对象之间的关联
IADORecordBindingPtr picRs(pRs);

file://调用_Recordset的Open方法取得Recordset对象
pRs->Open("SELECT * FROM Employee ORDER BY lname",
"dsn=pubs;uid=sa;pwd=;",
adOpenStatic, adLockOptimistic, adCmdText);

file://利用CCustomRS类中的宏定义,实现数据之间的绑定
file://如果绑定成功,我们就可以使用rs对象的属性了
TESTHR(picRs->BindToRecordset(&rs));

file://大家注意,这里的EndOfFile对应上文import语句中的rename("EOF", "EndOfFile"),其实就是EOF。rename的作用为了防止命名冲突。
while (!pRs->EndOfFile)
{
// Process data in the CCustomRs C++ instance variables.
printf("Name = %s %s/n",
(rs.m_ul_fnameStatus == adFldOK ? rs.m_ch_fname: ""),
(rs.m_ul_lnameStatus == adFldOK ? rs.m_ch_lname: ""));

// Move to the next row of the Recordset.
// Fields in the new row will automatically be
// placed in the CCustomRs C++ instance variables.

pRs->MoveNext();
}
}
catch (_com_error &e )
{
printf("Error:/n");
printf("Code = %08lx/n", e.Error());
printf("Meaning = %s/n", e.ErrorMessage());
printf("Source = %s/n", (LPCSTR) e.Source());
printf("Description = %s/n", (LPCSTR) e.Description());
}

file://清除COM对象实例
::CoUninitialize();
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值