通过COM使用ADO

原创 2003年05月14日 17:34:00

在Visual C++或C++ Builder中,我们可以通过访问ADO的COM对象来将对ADO的操作封装成一个类。首先,我们需要对MSADO15.DLL进行导入,让它生成类型库。在C++ Builder中,用TLIBIMP.EXE来生成ADODB_TLB.h,ADODB_TLB.cpp等文件,然后我们通过阅读类型库中的信息,从而可以写成这个类:
.h File
#ifndef ADOH
#define ADOH
#include "ADODB_TLB.h"
#include "utilcls.h"
#include <dstring.h>
class CValue
{
public:
     CValue();
     ~CValue();
     Variant m_value;
     BOOL AsBool();
     String AsString();
     int AsInt();
     float AsFloat();
     TDateTime AsDate();
};

class ADOConnection
{
public:
 ADOConnection();
 virtual ~ADOConnection();
public:
 _ConnectionPtr m_pConnection;
 BOOL  m_bConnectionOpen;
   BOOL  m_bInstance;
   int m_nOpenMode;
 BOOL  Open(BSTR dsn,BSTR uid,BSTR pwd);
};
class ADOrecordset
{
public:
 ADOrecordset();
 virtual ~ADOrecordset();
public:
   _ConnectionPtr m_pConnection;
 _RecordsetPtr  m_recordset;
 BOOL    m_bOpen;
 BOOL    SetConnect(_ConnectionPtr _pConnection);
 BOOL Open(WideString sql);
 HRESULT GetFieldValue(Variant idx,Variant * newVal);
 CValue GetFieldValue(String sName);
 CValue GetFieldValue(long index);
 HRESULT GetFieldCount(long &Count);//added by chenbin
 HRESULT GetFields(long index,String& sFieldList);//added by chenbin
 HRESULT GetFieldType(FieldPtr pField,String& strMsg,long& nResult);//added by chenbin
 HRESULT GetFieldType(String FieldName,String& strMsg,long& nResult);//added by chenbin
 BOOL    get_BOF();
 BOOL    get_EOF();
 HRESULT Prev();
 HRESULT Last();
 HRESULT Next();
 HRESULT First();
 HRESULT CloseRecordset(void);
};
#endif


.cpp File
#ifdef __BORLANDC__
#include <vcl.h>
#pragma hdrstop
#endif
#include "ADO.h"
file://----------Class CValue-------------------
CValue::CValue()
{

   file://If necessary,you may add codes here......
}
CValue::~CValue()
{
   file://If necessary,you may add codes here.........
}
BOOL CValue::AsBool()
{
   if(m_value.IsEmpty()) return false;
   else return m_value.AsType(varBoolean);
}
String CValue::AsString()
{
   if(m_value.IsEmpty()) return "";
   else return m_value.AsType(varString);
}
int CValue::AsInt()
{
   int m_int;
   if(m_value.IsEmpty()) return 0;
   else
   {
      switch(m_value.Type())
      {
         case varSmallint:
            m_int=m_value.AsType(varSmallint);
            break;
         case varInteger:
            m_int=m_value.AsType(varInteger);
            break;
         default:
            m_int=0;
      }
   }
   return m_int;
}
float CValue::AsFloat()
{
   float m_float;
   if(m_value.IsEmpty()) return 0;
   else
   {
      switch(m_value.Type())
      {
         case varSingle:
            m_float=m_value.AsType(varSingle);
            break;
         case varDouble:
            m_float=m_value.AsType(varDouble);
            break;
         default:
            m_float=0;
            break;
      }
   }
   return m_float;
}
TDateTime CValue::AsDate()
{
   file://1970-01-01 12:00:00 is invalid datetime
   TDateTime dt=StrToDateTime("1970-01-01 12:00:00");
   if(m_value.IsEmpty()) return dt;
   else return m_value.AsType(varDate);
}

file://----------------Class ADOConnection------------
ADOConnection::ADOConnection()
{
   m_bConnectionOpen= FALSE;
   m_bInstance=FALSE;
 file://If necessary,you may add codes here....
}
ADOConnection::~ADOConnection()
{
   m_bInstance=FALSE;
   m_bConnectionOpen=FALSE;
   file://If necessary,you may add codes here....
}
BOOL ADOConnection::Open(wchar_t* dsn,wchar_t* uid,wchar_t* pwd)
{
   HRESULT hr;
   if(!m_bInstance)
   {
      try
      {
         hr=m_pConnection.CreateInstance(__uuidof(Connection));
      }
      catch(Exception &e)
      {
         ::MessageBox(::GetActiveWindow(),e.Message.c_str(),"Error",MB_OK+MB_ICONERROR);
         return FALSE;
      }
      m_bInstance=true;
   }
   if(m_bConnectionOpen) return TRUE;
   try
   {
      hr=m_pConnection->Open(dsn,uid,pwd,adModeUnknown);
      m_nOpenMode=2;
   }
   catch(Exception &e)
   {
      ::MessageBox(::GetActiveWindow(),e.Message.c_str(),"Error",MB_OK+MB_ICONERROR);
      return FALSE;
   }
   m_bConnectionOpen=TRUE;
   hr=S_OK;
   return TRUE;
}
file://-------Class ADORecordset------------
ADOrecordset::ADOrecordset()
{
}
ADOrecordset::~ADOrecordset()
{
}
BOOL ADOrecordset::SetConnect(_ConnectionPtr _pConnection)
{
   if(_pConnection)
   {
      HRESULT hr=m_recordset.CreateInstance(__uuidof(Recordset));
      m_pConnection=_pConnection;
      if(SUCCEEDED(hr)==S_OK) return TRUE;
      else return FALSE;
   }
   else return FALSE;
}
BOOL ADOrecordset::Open(WideString sql)
{
   try
   {
      _CommandPtr m_Cmd("ADODB.Command");
      m_Cmd->_set_ActiveConnection(m_pConnection);
      m_Cmd->set_CommandText(sql);
      m_Cmd->set_CommandType(adCmdText);
      m_recordset=m_Cmd->Execute(NULL,NULL,adCmdText);
      m_bOpen=true;
   }
   catch(Exception &e)
   {
      m_bOpen=FALSE;
      return FALSE;
   }
   return TRUE;
}
HRESULT ADOrecordset::GetFieldValue(Variant idx,Variant * newVal)
{
   FieldsPtr *Fields=0;
   FieldPtr *Field=0;
   HRESULT hr=m_recordset->get_Fields(Fields);
   if(hr==S_OK)
   {
      hr=(*Fields)->get_Item(idx,Field);
      if(hr==S_OK)
      {
         hr=(*Field)->get_Value(*newVal);
      }
   }
   return hr;

}
CValue ADOrecordset::GetFieldValue(String sName)//Get Field's value according to the field's name
{
   FieldsPtr *Fields=0;
   FieldPtr *Field=0;
   CValue v;
   Variant idx=sName;
   if(m_recordset->get_Fields(Fields)==S_OK)
   {
      if((*Fields)->get_Item(idx,Field)==S_OK)
      {
         v.m_value=(*Field)->get_Value();
      }
   }
   return v;
}
CValue ADOrecordset::GetFieldValue(long index)
{
   FieldsPtr* Fields=0;
   FieldPtr* Field=0;
   CValue v;
   if(m_recordset->get_Fields(Fields)==S_OK)
   {
      if((*Fields)->get_Item(index,Field)==S_OK)
      {
         v.m_value=(*Field)->get_Value();
      }
   }
   return v;
}
HRESULT ADOrecordset::GetFieldCount(long &Count)
{
   FieldsPtr* Fields;
   HRESULT hr;
   hr=m_recordset->get_Fields(Fields);
   if(hr==S_OK)
   {
      hr=(*Fields)->get_Count(&Count);
   }
   return hr;
}
HRESULT ADOrecordset::GetFields(long index,String& sFieldList)
{
   FieldsPtr* Fields;
   FieldPtr* Field;
   HRESULT hr;
   WideString FieldName;
   long rec=0;
   hr=m_recordset->get_Fields(Fields);
   if(hr==S_OK)
   {
      hr=(*Fields)->get_Count(&rec);
      if(hr==S_OK)
      {
         for(int i=0;i<hr;i++)
         {
            hr=(*Fields)->get_Item(i,Field);
            if(hr==S_OK)
            {
               hr=(*Field)->get_Name(&FieldName);
               if(hr==S_OK)
               {
                  sFieldList+=(String)FieldName;
               }
            }
         }
      }
   }
   return hr;
}
HRESULT GetFieldType(FieldPtr pField,String& strMsg,long& nResult)
{
   file://Nowadays I don't use the function,which will be used according to needs in the future
   return S_OK;
}
HRESULT GetFieldType(String FieldName,String& strMsg,long& nResult)
{
   file://Nowadays I don't use the function,which will be used according to needs in the future
   return S_OK;
}
BOOL    ADOrecordset::get_BOF()
{
   BOOL bFlag=m_recordset->get_BOF();
   return bFlag;
}
BOOL    ADOrecordset::get_EOF()
{
   BOOL bFlag=m_recordset->get_EOF();
   return bFlag;
}
HRESULT ADOrecordset::Prev()
{
   HRESULT hr=m_recordset->MovePrevious();
   return hr;
}
HRESULT ADOrecordset::Last()
{
   HRESULT hr=m_recordset->MoveLast();
   return hr;
}
HRESULT ADOrecordset::Next()
{
   HRESULT hr=m_recordset->MoveNext();
   return hr;
}
HRESULT ADOrecordset::First()
{
   HRESULT hr=m_recordset->MoveFirst();
   return hr;
}
HRESULT ADOrecordset::CloseRecordset(void)
{
   HRESULT hr=m_recordset->Close();
   return hr;
}
写完这个类之后,以后在程序中就可以直接使用这个类来对ADO进行访问,写一个简单的测试代码:
假定我已在ODBC中新建一数据源:DSN=Test,Username=chenbin,Password=caiyao,那么如果想用ADO对该数据源进行访问的话,就可以用下面的代码:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   ADOConnection m_Connection;
   ADOrecordset rst;
   if(m_Connection.Open(L"Test",L"chenbin",L"caiyao"))
   {
      if(rst.SetConnect(m_Connection.m_pConnection))
      {
         if(rst.Open("select * from family"))
         {
            if(rst.First()==S_OK)
            {
               while(!rst.get_EOF())
               {
                  Memo1->Lines->Add(rst.GetFieldValue("name").AsString());
                  rst.Next();
               }
            }
         }
      }
   }
}

 

 

Delphi多线程下的ADO编程

前言: 几个月前接到一个任务:将一后台程序访问数据库的方式从BDE改为ADO,原因是由于业务量的增加,通过BDE不论是向数据库写入数据还是从数据库中读出数据的速度都变得无法忍受,大家都知道ADO在数...
  • youthon
  • youthon
  • 2013年05月06日 16:13
  • 3123

Delphi下的原生ADO使用方法

本文向您揭示在Delphi中使用ADO是如何轻而易举,结合了ADO的Delphi应用程序,将不再依赖于BDE。 ADO的精髓在于利用简单的COM指令来快速方便的访问ODBC数据源,微软的表格、...
  • Hmillet
  • Hmillet
  • 2016年03月30日 09:55
  • 2435

用ADO方式连接SQL SEVER的几个简单步骤

其步骤一般分为: (1)     引入ADO动态库文件 (2)     初始化COM环境 (3)     连接数据库操作数据 1、引入ADO库文件,一般是在stdAfx.h文件中添加(在你需要添加...
  • qq_15328161
  • qq_15328161
  • 2015年04月29日 14:13
  • 1690

ADO对象之Connection用法总结

Connection对象的属性有如下几个: 1.ConnectionString:是连接字符串,通过传递包含一系列由分号分隔的“argument=value”语句的详细连接字符串,可指定用于建立连接...
  • hfchenle
  • hfchenle
  • 2016年07月05日 16:49
  • 152

vs2008下MFC中采用ado连接MySQL(ODBC、非ODBC或C API方式)

其实,以前弄过sql,mysql应该是顺理成章很简单的事情,但很无奈,傻傻地弄了很久,还请教了别人,别人告诉我的跟我在网上查到的都是一样的,但还是不行,归根接地就是“mysql-connector-o...
  • xuyuefei1988
  • xuyuefei1988
  • 2013年05月06日 20:52
  • 8048

MFC中ADO方式操作数据库实例

连接ACCESS为例:  C++代码   //头文件   #pragma once           #include "math.h"           #im...
  • u011135902
  • u011135902
  • 2015年04月15日 18:08
  • 496

【VBA研究】使用ADO组件的两种方式----引用法和创建法

作者:iamlaosong 1、引用法      引用ADO相关组件:打开VBA编辑器,在菜单中点选“工具”--》“引用”。确保“Microsoft ActiviteX Data Objects 2....
  • iamlaosong
  • iamlaosong
  • 2015年04月17日 14:27
  • 2916

用ADO操作数据库的方法步骤

学习ADO时总结的一些经验     用ADO操作数据库的方法步骤   ADO接口简介 ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr...
  • gongluck93
  • gongluck93
  • 2016年09月19日 10:33
  • 2705

ADO方式连接数据库

ADO方式连接数据库分为如下步骤: 1.ADO对象的导入 在使用ADO技术时需要导入一个ADO动态链接库msado15.dll。该动态库位于系统盘下的"Program Files\Common Fil...
  • hola_f
  • hola_f
  • 2016年08月03日 16:32
  • 2874

VS2010通过ADO链接SQL Server的方法体会

这里时我花了一天多的时间查找各种资料和网站上面整理出来的有关MFC通过ADO的方式连接SQL server数据库的方法,各种书籍或者网站都只说了其中的一些,只是举了一些成功的例子,因为不同人不同电脑的...
  • woshimalingyi
  • woshimalingyi
  • 2014年12月15日 02:21
  • 2840
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:通过COM使用ADO
举报原因:
原因补充:

(最多只允许输入30个字)