ADO数据库编程入门 liandong(原作)[1]

[入库:2005年8月18日] [更新:2007年3月27日]

本文简介:选择自 westerly 的 blog

ado数据库编程入门


 李安东编写


2002年2月28日


摘要  本文简要介绍了在vc++ 6.0中使用 ado进行客户端数据库编程的基本步骤,以及常见问题的解决方法,可供入门级的参考之用。

关键字  ado  vc++   数据库编程

ado 是目前在windows环境中比较流行的客户端数据库编程技术。ado是建立在ole db底层技术之上的高级编程接口,因而它兼具有强大的数据处理功能(处理各种不同类型的数据源、分布式的数据处理等等)和极其简单、易用的编程接口,因而得到了广泛的应用。而且按微软公司的意图,ole db和ado将逐步取代 odbc和dao。现在介绍ado各种应用的文章和书籍有很多,本文着重站在初学者的角度,简要探讨一下在vc++中使用ado编程时的一些问题。我们希望阅读本文之前,您对ado技术的基本原理有一些了解。
一、在vc++中使用ado编程
ado实际上就是由一组automation对象构成的组件,因此可以象使用其它任何automation对象一样使用ado。ado中最重要的对象有三个:connection、command和recordset,它们分别表示连接对象、命令对象和记录集对象。如果您熟悉使用mfc中的odbc类(cdatabase、crecordset)编程,那么学习ado编程就十分容易了。
使用ado编程时可以采用以下三种方法之一:
1、使用预处理指令#import
#import "c:\program files\common files\system\ado\msado15.dll" \
   no_namespace rename("eof", "endoffile")
但要注意不能放在stdafx.h文件的开头,而应该放在所有include指令的后面。否则在编译时会出错。
程序在编译过程中,vc++会读出msado15.dll中的类型库信息,自动产生两个该类型库的头文件和实现文件msado15.tlh和msado15.tli(在您的debug或release目录下)。在这两个文件里定义了ado的所有对象和方法,以及一些枚举型的常量等。我们的程序只要直接调用这些方法就行了,与使用mfc中的coledispatchdriver类调用automation对象十分类似。
2、使用mfc中的cidispatchdriver
就是通过读取msado15.dll中的类型库信息,建立一个coledispatchdriver类的派生类,然后通过它调用ado对象。
3、直接用com提供的api
 如使用如下代码:
 clsid clsid;
 hresult hr = ::clsidfromprogid(l"adodb.connection", &clsid);
 if(failed(hr))
 {...}
 ::cocreateinstance(clsid, null, clsctx_server, iid_idispatch, (void **)
      &pdispatch);
 if(failed(hr))
 {...}
以上三种方法,第一和第二种类似,可能第一种好用一些,第三种编程可能最麻烦。但可能第三种方法也是效率最高的,程序的尺寸也最小,并且对ado的控制能力也最强。
据微软资料介绍,第一种方法不支持方法调用中的默认参数,当然第二种方法也是这样,但第三种就不是这样了。采用第三种方法的水平也最高。当你需要绕过ado而直接调用ole db底层的方法时,就一定要使用第三种方法了。
ado编程的关键,就是熟练地运用ado提供的各种对象(object)、方法(method)、属性(property)和容器(collection)。另外,如果是在ms sql或oracle等大型数据库上编程,还要能熟练使用sql语言。
二、使用#import方法的编程步骤
这里建议您使用#import的方法,因为它易学、易用,代码也比较简洁。
1、 添加#import指令
打开stdafx.h文件,将下列内容添加到所有的include指令之后:
#include <icrsint.h>   //include support for vc++ extensions
#import "c:\program files\common files\system\ado\msado15.dll" \
   no_namespace rename("eof", "adoeof")
其中icrsint.h文件包含了vc++扩展的一些预处理指令、宏等的定义,用于com编程时使用。
2、定义_connectionptr型变量,并建立数据库连接
建立了与数据库服务器的连接后,才能进行其他有关数据库的访问和操作。ado使用connection对象来建立与数据库服务器的连接,所以它相当于mfc中的cdatabase类。和cdatabase类一样,调用connection对象的open方法即可建立与服务器的连接。
数据类型 _connectionptr实际上就是由类模板_com_ptr_t而得到的一个具体的实例类,其定义可以到msado15.tlh、comdef.h 和comip.h这三个文件中找到。在msado15.tlh中有:
_com_smartptr_typedef(_collection, __uuidof(_collection));
经宏扩展后就得到了_connectionptr类。_connectionptr类封装了connection对象的idispatch接口指针,及一些必要的操作。我们就是通过这个指针来操纵connection对象。类似地,后面用到的_commandptr和_recordsetptr类型也是这样得到的,它们分别表示命令对象指针和记录集对象的指针。
(1)、连接到ms sql server
注意连接字符串的格式,提供正确的连接字符串是成功连接到数据库服务器的第一步,有关连接字符串的详细信息参见微软msdn library光盘。
本例连接字符串中的server_name,database_name,user_name和password在编程时都应该替换成实际的内容。
 _connectionptr pmyconnect=null;
 hresult hr=pmyconnect.createinstance(__uuidof(connection)));
 if(failed(hr))return;

_bstr_t strconnect="provider=sqloledb; server=server_name;"
  "database=database_name; uid=user_name; pwd=password;" 
//connecting to the database server now:
 try{pmyconnect->open(strconnect,"","",null);}
 catch (_com_error &e)
 {
  ::messagebox(null,e.description(),"警告",mb_ok | mb_iconwarning);
 }

注意connection对象的open方法中的连接字符串参数必须是bstr或_bstr_t类型。另外,本例是直接通过ole db provider建立连接,所以无需建立数据源。
(2)、通过odbc driver连接到database server
连接字符串格式与直接用odbc编程时的差不多:
_bstr_t strconnect="dsn=datasource_name; database=database_name; uid=user_name; pwd=password;"
此时与odbc编程一样,必须先建立数据源。
3、定义_recordsetptr型变量,并打开数据集
定义_recordsetptr型变量,然后通过它调用recordset对象的open方法,即可打开一个数据集。所以recordset对象与mfc中的crecordset类类似,它也有当前记录、当前记录指针的概念。如:
 _recordsetptr m_precordset;
 if(!failed(m_precordset.createinstance( __uuidof( recordset )))
 {
  m_pdoc->m_initialized=false;
  return;
 }

 try{
  m_precordset->open(_variant_t("mytable"),
            _variant_t((idispatch *)pmyconnect,true), adopenkeyset,
            adlockoptimistic, adcmdtable);
 }
 catch (_com_error &e)
 {
  ::messagebox(null,"无法打开mytable表。","提示",
mb_ok | mb_iconwarning);
 }
recordset对象的open方法非常重要,它的第一个参数可以是一个sql语句、一个表的名字或一个命令对象等等;第二个参数就是前面建立的连接对象的指针。此外,用connection和command对象的execute方法也能得到记录集,但是只读的。
4、读取当前记录的数据
我认为读取数据的最方便的方法如下:
 try{
  m_precordset->movefirst();  
  while(m_precordset->adoeof==variant_false) 
  {
   //retrieve column&s value: 
   cstring sname=(char*)(_bstr_t)(m_precordset->fields->getitem

本文关键:,ADO,
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top