使用ADO数据库编程.docx
- 文档编号:7336408
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:10
- 大小:21.85KB
使用ADO数据库编程.docx
《使用ADO数据库编程.docx》由会员分享,可在线阅读,更多相关《使用ADO数据库编程.docx(10页珍藏版)》请在冰豆网上搜索。
使用ADO数据库编程
使用ADO数据库编程
ADO(ActiveXDataObject)是Microsoft数据库应用程序开发的新接口,是建立在OLEDB之上的高层数据库访问技术。
ADO非常简单易用,甚至比ODBCAPI、DAO、RDO都要容易使用,并不失灵活性。
本节将讨论如何使用ADO进行数据库的开发,介绍ADO库定义文件,讨论用Connection对象连接数据库、通过Connection、Command对象执行SQL命令及利用Recordset对象取得结果记录集进行查询、处理,下面分别介绍。
1.1导入ADO的动态链接库
用#import指令引入ADO类型库,在使用的文件中加入如下语句#import"c:
\programfiles\commonfiles\system\ado\msado15.dll"no_namespacerename("EOF","adoEOF")
这句话的作用是编译的时候系统会为我们生成msado15.tlh,ado15.tli两个头文件来定义ADO库,即加载ADO动态库(msado15.dll)。
其中,no_namespace表明不使用命名空间,rename("EOF","adoEOF")表明把ADO中用到的EOF改为adoEOF,防止发生命名冲突。
几点说明:
❑该代码需要在一行中完成,如果写成两行或者多行,行末要加上“”符号,表示把这几行看成一行。
❑读者的编程环境中msado15.dll不一定在这个目录下,请按实际情况修改。
❑在编译的时候可能会出现warning C4146警告,对此微软在MSDN中作了说明,并建议不要理会这个警告。
1.2初始化ADO控件环境
ADO库是一组COM动态库,这意味应用程序在调用ADO前,必须初始化OLE/COM库环境。
初始化OLE/COM库环境的代码如下:
:
:
CoInitialize(NULL);/*初始化OLE/COM库环境*/
别忘了最后要释放资源:
:
:
CoUninitialize();/*释放程式占用的COM资源*/
如果需要界面支持可以通过另外一个函数实现。
if(!
AfxOleInit())/*初始化OLE/COM库环境*/
{
printf("OLE初始化出错!
");
return0;
}
每次应用程序启动时,需要通过函数AfxOleInit()或CoInitialize()实现初始化OLE/COM库环境。
本书中相关实例是使用CoInitialize()来完成初始化。
1.3ADO库接口
ADO库包含三个基本接口:
_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。
下面分别讨论各接口功能描述及使用方法。
1._ConnectionPtr接口
_ConnectionPtr是一个连接接口,返回一个记录集或一个空指针。
它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。
通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句。
初始化COM环境后,创建与数据库的连接最佳方法是声明一个Connection对象指针_ConnectionPtr,并把它用于和Connection对象进行的所以交互中。
一旦声明了Connection对象指针,可以通过创建一个Connection对象的实例(调用函数CreateInstance()),并把Connection对象的UUID(接口的ID)作为唯一的参数传给它,从而初始化它。
_ConnectionPtr接口执行过程是先创建一个_ConnectionPtr接口实例,接着指向并打开一个ODBC数据源。
下面给出使用_ConnectionPtr创建一个基于DSN和非DSN的数据连接的实例。
(1)使用_ConnectionPtr基于非DSN数据连接语句。
如果没有注册数据源,可直接通过连接字符串实现数据库的连接。
分别针对SQLSERVER、ORACLE和Access数据库给出连接字符串的构造实例,读者可直接使用对应的例句。
(2)连接SQLSERVER。
_ConnectionPtrpCon;/*定义pCon指针*/
pCon.CreateInstance(__uuidof(Connection));/*初始化pCon指针*/
strConn.="driver={SQLServer};Server=kobe;DATABASE=test;UID=sa;PWD=";
pCon->Open((_bstr_t)strConn,"","",adModeUnknown);
上述语句中,kobe是服务器名。
如果连接本地数据库,可以是“172.0.0.1”或“.”或“localhost”都是可以的。
test是数据库名称,SQLSERVER登录的用户名sa和密码为空,这些参数可通过SQLSERVER的企业管理器更改。
(3)连接Access。
CStringstrConn;
_ConnectionPtrpCon;
pCon.CreateInstance(__uuidof(Connection));
strConn="driver={MicrosoftAccessDriver(*.mdb};DBQ=E:
\\test.mdb";
pCon->Open((_bstr_t)strConn,"","",adModeUnknown);
上述语句中DBQ是Access数据库的完整路径名。
例如,“D:
\\DB\\test.mdb”注意描述路径需要有两个反斜杠。
(4)使用_ConnectionPtr基于DSN数据连接语句。
如果已经有注册的数据源“test”可用另外一种方式连接数据库。
_ConnectionPtrpCon;
pCon.CreateInstance(__uuidof(Connection));
pCon->Open("DSN=test;UID=sa;PWD=","","",-1);
语句中的UID、PWD分别为SQLSERVER登录的用户名sa和密码为空。
2._CommandPtr接口
_CommandPtr接口返回一个记录集或一个空指针。
它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。
在使用_CommandPtr接口时,不仅可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。
如果你要频繁访问数据库,并要返回很多记录集,那么,你应该使用全局_ConnectionPtr接口创建一个数据连接,然后使用_CommandPtr接口执行存储过程和SQL语句。
使用_ConnectionPtr接口返回一个记录集不是一个好的使用方法。
通常使用它创建一个数据连接,然后使用其它对象执行数据输入输出操作。
3._RecordsetPtr接口
_RecordsetPtr接口是指向ADO的Recordset对象的指针,它对记录集提供了更多的控制功能。
例如,记录锁定,游标控制等实现对记录的插入、删除及更新操作。
同_CommandPtr接口一样,它不一定要使用一个已经创建的数据连接,可以用一个连接串代替连接指针赋给_RecordsetPtr的connection成员变量,让它自己创建数据连接。
如果需要使用多个记录集,可以与Command对象一样使用已经创建了数据连接的全局_ConnectionPtr接口,然后使用_RecordsetPtr执行存储过程和SQL语句。
/***********************基本流程***********************************/
(1)初始化COM库,引入ADO库定义文件
(2)用Connection对象连接数据库
(3)利用建立好的连接,通过Command对象执行SQL命令,或利用Recordset对象取得结果记录集进行查询、处理。
(4)使用完毕后关闭连接释放对象。
//操作的详细步骤:
/*******************【1】COM库的初始化*************************************/
可以使用AfxOleInit()或:
:
CoInitialize(NULL)来初始化COM库,通常在CWinApp:
:
InitInstance()的函数中完成,请看如下代码:
BOOLCADOTest1App:
:
InitInstance()
{
AfxOleInit();......
}
/***********************【2】用#import指令引入ADO类*************************/
在stdafx.h中加入如下语句:
#import"c:
\programfiles\commonfiles\system\ado\msado15.dll"no_namespacerename("EOF","adoEOF")
其作用同#include类似,编译时系统会生成msado15.tlh,ado15.tli两个C++头文件来定义ADO库。
/***********************【3】创建Connection对象并连接数据库***************/
首先我们需要添加一个指向Connection对象的指针:
_ConnectionPtrm_pConnection;
BOOLCADOTest1Dlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
try
{
HRESULThr=m_pConnection.CreateInstance("ADODB.Connection");//创建Connection对象
if(SUCCEEDED(hr))
{
hr=m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=test.mdb","","",adModeUnknown);//连接数据库
//hr=m_pConnection->Open("driver={SQLServer};Server=.;DATABASE=xxx;UID=sa;PWD=","","",adModeUnknown); } }
catch(_com_errore)
//COM错误取得,当执行COM功能的时候,如果出错,可以捕捉到_com_error的异常
{
CStringstrComError;
strComError.Format("错误编号:
%08lx\n错误信息:
%s\n错误源:
%s\n错误描述:
%s",
e.Error(), //错误编号
e.ErrorMessage(), //错误信息
(LPCSTR)e.Source(), //错误源
(LPCSTR)e.Description()); //错误描述
:
:
MessageBox(NULL,strComError,"错误",MB_ICONEXCLAMATION);
}
}
◆常用的数据库连接方法:
(1)通过JET数据库引擎对ACCESS2000数据库的连接
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=C:
\\test.mdb","","",adModeUnknown);
(2)通过DSN数据源对任何支持ODBC的数据库进行连接:
m_pConnection->Open("DataSource=adotest;UID=sa;PWD=;","","",adModeUnknown);
//m_pConnection->Open("DSN=test;","","",0); //连接叫作test的ODBC数据源
(3)不通过DSN对SQLSERVER数据库进行连接:
m_pConnection->Open("driver={SQLServer};Server=127.0.0.1;DATABASE=vckbase;UID=sa;PWD=139","","",adModeUnknown);
其中Server是SQL服务器的名称,DATABASE是库的名称
/***********************【4】执行SQL命令并取得结果记录集***********************/
为了取得结果记录集,定义一个指向Recordset对象的指针:
_RecordsetPtrm_pRecordset;
并为其创建Recordset对象的实例:
m_pRecordset.CreateInstance("ADODB.Recordset");
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
//////////////////////////////////////////////////////////////////////////
注:
VARIANT数据类型和VC++数据类型之间的转换
//定义
_variant_tva; CStringstr;
1)带变量的SQL语句需要把str转换_variant_t
str.Format("select*fromtable wherexx=%s",m_str)
...Execute(v_bstr_t(str)...
2)GetCollect取数据需要把_variant_t转换str
str=(LPCTSTR)(_bstr_t)va
//////////////////////////////////////////////////////////////////////////
◆
(1)利用Connection对象的Execute方法执行SQL命令
Execute方法的原型如下所示:
_RecordsetPtrConnection15:
:
Execute(_bstr_tCommandText,VARIANT*RecordsAffected,longOptions)
其中
CommandText 是命令字串,通常是SQL命令。
RecordsAffected 是操作完成后所影响的行数,
Options 表示CommandText中内容的类型,Options可以取如下值之一:
adCmdText:
表明CommandText是文本命令
adCmdTable:
表明CommandText是一个表名
adCmdProc:
表明CommandText是一个存储过程
adCmdUnknown:
未知
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
try
{
_variant_tra;
m_pConnection->Execute("CREATETABLE学生信息(学号INTEGER,姓名TEXT,年龄INTEGER,生日DATETIME)",&ra,adCmdText);
m_pConnection->Execute("INSERTINTO学生信息(学号,姓名,年龄,生日)VALUES(,'程红秀',22,'1982-08-16')",&ra,adCmdText);//往表格里面添加记录
m_pRecordset=m_pConnection->Execute("SELECTCOUNT(*)FROM学生信息",&ra,adCmdText); //执行SQL统计命令得到包含记录条数的记录集
_variant_tvCount=m_pRecordset->GetCollect((_variant_t)(long)(0));
//取得第一个字段的值放入vCount变量
m_pRecordset->Close();
CStringmessage;
message.Format("共有%d条记录",vCount.lVal);
AfxMessageBox(message);
}
catch(_com_errore)
{ ...}
◆
(2)直接用Recordset对象进行查询取得记录集
例如
m_pRecordset->Open("SELECT*FROM学生信息",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
Open方法的原型是这样的:
HRESULTRecordset15:
:
Open(const_variant_t&Source,const_variant_t&ActiveConnection,enumCursorTypeEnumCursorType,enumLockTypeEnumLockType,longOptions)
其中:
①Source是数据查询字符串
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
enumCursorTypeEnum
{
adOpenUnspecified=-1, //不作特别指定
adOpenForwardOnly=0, //前滚静态光标。
这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。
但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
adOpenKeyset=1, //采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
adOpenDynamic=2, //动态光标。
所有数据库的操作都会立即在各用户记录集上反应出来。
adOpenStatic=3 //静态光标。
它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
};
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
enumLockTypeEnum
{
adLockUnspecified=-1, //未指定
adLockReadOnly=1, //只读记录集
adLockPessimistic=2, //悲观锁定方式。
数据在更新时锁定其它所有动作,这是最安全的锁定机制
adLockOptimistic=3, //乐观锁定方式。
只有在你调用Update方法时才锁定记录。
在此之前仍然可以做数据的更新、插入、删除等动作
adLockBatchOptimistic=4, //乐观分批更新。
编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
};
⑤Options请参考本文中对Connection对象的Execute方法的介绍
/***********************【5】记录集的遍历、更新*************************/
根据我们刚才通过执行SQL命令建立好的学生信息表,它包含四个字段:
学号,姓名,年龄,生日.以下的代码实现:
打开记录集,遍历所有记录,删除第一条记录,添加三条记录,移动光标到第二条记录,更改其年龄,保存到数据库。
try
{
_variant_tvUsername,vBirthday,vID,vOld;
_RecordsetPtrm_pRecordset;
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pRecordset->Open("SELECT*FROM学生信息",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
while(!
m_pRecordset->adoEOF)
{
vID=m_pRecordset->GetCollect(_variant_t((long)0)); //取得第1列的值,从0开始计数,你也可以直接给出列的名称,如下一行
vUsername=m_pRecordset->GetCollect("姓名"); //取得姓名字段的值
vOld=m_pRecordset->GetCollect("年龄");
vBirthday=m_pRecordset->GetCollect("生日");
TRACE("id:
%d,姓名:
%s,年龄:
%d,生日:
%s\r\n",
vID.lVal,
(LPCTSTR)(_bstr_t)vUsername,
vOld.lVal,
(LPCTSTR)(_bstr_t)vBirthday); //在DEBUG方式OUTPUT窗口输出记录集中的记录
m_pRecordset->MoveNext(); //移到下一条记录
}
m_pRecordset->MoveFirst(); //移到首条记录
m_pRecordset->Delete(adAffectCurrent); //删除当前记录
for(inti=0;i<3;i++) //添加三条新记录并赋值
{
m_pRecordset->AddNew(); //添加新记录
m_pRecordset->PutCollect("学号",_variant_t((long)(i+10)));
m_pRecordset->PutCollect("姓名",_variant_t("王斌年"));
m_pRecordset->PutCollect("年龄",_variant_t((long)21));
m_pRecordset->PutCollect("生日",_variant_t("1930-3-15"));
}
m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst)); //从第一条记录往下移动一条记录,即移动到第二条记录处
m_pRecordset->PutCollect(_variant_t("年龄"),_variant_t((long)45)); //修改其年龄
m_pRecordset->Update(); //
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 使用 ADO 数据库 编程