VC基于ADO技术访问Access数据库
2013-03-29冯晓星马晓静
冯晓星 马晓静
(电子工程学院 安徽 合肥 230037)
1 引言
在开发数据库应用软件中,Visual C++提供了多种访问接口,相比较早期基于ODBC的DAO、RDO等技术,建立在OLE/DB之上的ADO(ActiveX DataObjects)技术无疑更加高效快捷。ADO能够处理任何类型的数据,而不考虑它们的格式和存储方法。这些数据源不仅包括关系型数据库,也包含非关系型数据库。由于它具有强大的数据处理功能和极其简单、易用的特点,因而已成为当前数据库开发的主流[1,2]。
2 ADO对象与编程初始环境
2.1 ADO对象简介
ADO数据库接口继承了DAO和RDO所使用的对象模型,并加以改进,包含了较少的对象、更多的属性方法(和参数)和事件。ADO有7个对象:Command对象、Connection对象、Recordset对象、Parameter对象、Field 对象、Error对象和Property对象,其中前3个对象是主体对象也是基本对象,它们可以被独立创建和释放。
在访问数据库之前需建立与数据源的连接并保持,这一过程用Connection对象实现,通过和SQL语句结合创建一个连接。利用Command对象和Recordset对象都可在执行数据库操作后返回一个记录集。和Connection对象一样,Command对象通过与SQL语句相结合的方法可以完成对数据库的简单快捷操作,而Recordset对象可以提供更多的数据库操作控制功能,如记录锁定,游标控制等[3]。
2.2 ADO编程环境初始化
使用ADO访问数据库之前有2个准备步骤。
⑴导入ADO类型库
ADO DLL(msado15.dll)中定义了ADO类,在其内部称为类型库。一般在stdafx.h头文件中,使用#import指令导入ADO类型库,以此创建一组C++头文件,程序语句如下:
根据Windows操作系统版本的不同,动态链接库文件可能是msado10.dll、msado15.dll或msado20.dll,需根据实际情况进行修改。no_namespace的意思是该应用程序中,ADO对象的命名不存在和其他对象冲突的情况,不使用命名空间,重命名EOF和BOF是为了避免与其他库中的已定义的EOF和BOF冲突。
⑵初始化COM库
因为ADO库是一个COM动态链接库,所以使用ADO对象之前必须初始化COM库环境,调用结束后再释放资源。初始化的代码为函数::Co Initialize(NULL),释放程序占用资源的代码为:CoUninitialize(),分别在VC工程应用类的InitInstance()成员函数和ExitInstance()成员函数中添加。
3 用ADO对象访问数据库
3.1 连接数据库
对于ADO的3个主体对象,动态链接库分别定义了3个智能指针,_ConnectionPtr指针对应 Connection对象、_CommandPtr指针对应Command对象,_RecordsetPtr指针对应Recordset对象。操作数据库之前需建立一个数据库连接,其操作步骤是:首先声明一个_ConnectionPtr指针并调用CreateInstance()函数创建一个Connection对象实例,然后调用open()函数建立到数据源的连接。
连接Access数据库的示例程序代码如下:
上面代码用try、catch语句进行错误捕捉,因为连接数据库时经常会发生意想不到的错误。“Microsoft.Jet.OLEDB.4.0”代表通过JET数据库引擎连接数据库,“DataBase.mdb”是登录的数据库名,可根据具体情况进行修改,数据库的用户ID和密码为缺省,当前的许可权未设置。
在应用程序中,一般在使用完成数据库后,应该关闭与数据源的连接。ADO在关闭连接的同时,也将关闭所有使用这个连接的ADO对象。关闭连接的代码如下:
3.2 操作记录集
要操作访问数据库,就必须先打开记录集。利用Command对象和Recordset对象结合SQL语句均可得到记录集。
3.2.1 利用Command对象来执行SQL命令
声明一个_CommandPtr指针并调用CreateInstance()函数创建一个Command对象实例,利用Execute方法得到记录集。代码如下:
利用Select查询语句,返回一个记录集,可先定义一个记录集指针,然后指向返回的记录集。
3.2.2 直接利用Recordset对象进行查询
在ADO数据库编程中,Recordset对象代表一个表的记录集或者是一个SQL语句或存储过程的执行结果。通过Recordset对象就可以更方便地进行查询、添加记录、修改记录和删除记录等的操作。其操作步骤是:首先声明一个_RecordsetPtr指针并调用CreateInstance()函数创建一个Recordset对象实例,然后调用Open()函数打开记录集。Open()函数原型如下:
其中,参数Source用于指定打开记录集的数据源,它可以是Command对象变量、SQL语句、表名或存储过程;ActiveConnection是一个连接对象的变量名或者是一个包含连接信息的字符串,用于指定是在哪一个连接中打开记录集;CursorType是一个CursorTypeEnum枚举类型常量,用于指定打开记录集时使用的游标,取值可以是adOpenStatic(静态游标)、adOpenDynam ic(动态游标)、adOpenForwardOnly(前向游标)和adOpenKeyset(键集游标)之一;LockType是一个LockTypeEnum枚举类型常量,用于指定打开记录集时使用的锁定类型,取值可以是adLockReadOnly(只读)、adLockPessim istic(悲观锁定)、adLockOptim istic(乐观锁定)和adLockBatchOptim istic(乐观批量更新)之一。Options是一个选项,表示ADO如何解释源数据,取值可以是adCmdText(Source是文本)、adCmdTable(表名)、adCmdStoreProc(存储过程)、adCmdUnknow n(未知)[4]。
示例程序代码如下:
对记录集的操作完成后,应关闭记录,释放占用的系统资源。调用Recordset对象的Close()函数可以关闭记录集,示例代码如下:
3.2.3 在记录集中定位
一个数据库由若干个表组成,表的行称为记录。ADO对象若要访问记录,需要先将游标停在记录集的该行前,即定位。Recordset对象提供了 4个成员函数:MovePrevious()、M oveNext()、M oveFirst()和 M oveLast(),控制游标移动,以进行定位。MoveFirst()是将游标移至表中的第一条记录,MoveLast()是将游标移至表中最后一条记录,M ovePrevious()是将游标移至当前记录的前一条记录,M oveNext()是将是将游标移至当前记录的后一条记录。代码如下:
这里通过if语句判断游标是否已移到了第一条记录的前面(Before of File),返回一个布尔值。同理,通过判断Recordset对象属性adoEOF的值,就可以知道游标是否移到了最后一条记录的后面(End of File)。
3.2.4 获取或修改字段的值
一行记录里可能有很多属性,即字段。游标定位好之后,通过调用GetCollect()函数,就可以获取当前记录中各个字段的值。该函数的原型如下:
其中,参数Index可以是要获取值的字段的索引号,也可以是要获取值的字段的名称[5,6]。
例如,现要获取当前记录的时间“Time”字段的值,代码如下:
通过调用PutCollect()函数,可以修改当前记录各字段的值。该函数的原型如下:
其中,参数Index的含义与GetCollect()函数中相同;参数pvar用于给出修改值,它可以是一个具体值,也可以是一个变量。
例如,将当前记录的“Time”字段的值改为“2012/12/7”,示例代码如下:
如果第2个参数给出的是CString型变量,则需要进行类型转换。示例代码如下:
4 结束语
综上所述,建立在OLE/DB基础之上的ADO封装了具体访问数据库的细节,使程序员从具体的数据库管理软件中解放出来,即使对OLE/DB,COM不了解也能轻松应用。通过利用ADO对象可方便快捷地连接数据库并操作,使得软件开发的周期大大缩短,并具有维护方便可靠的优点。
[1]刘天印.基于VC++的数据库访问技术的比较与选择[J].黄石:黄石理工学院学报,2005(4):15-18.
[2]史嘉权.数据库系统概论[M].北京:高等教育出版社,2006:10-15.
[3]王聪华.ADO访问数据库实例剖析[J].计算机应用研究,2002(5):159-160.
[4][美]DavisChapman著,骆长乐译.常用VisualC++6.0[M].北京:清华大学出版社,1999.
[5]郑阿奇.VisualC++教程[M].北京:机械工业出版社,2004.
[6]魏 朗,陈 涛.VisualC++程序设计攻略教程[M].西安:西安电子科技出版社,2004.