您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > MFC ODBC 编程
第6章MFCODBC编程为了简化开发人员编写数据库应用程序,VC++的在其基础类库(MFC)里对ODBCAPI进行了封装,实现了一个面向对象的数据库编程接口,使VC++的数据库变得更加容易。本章首先对MFCODBC的概貌进行简要介绍,然后讲述利用MFCODBC进行数据库开发的技巧,最后将通过具体数据库开发实例,详细讲述通过MFCODBC开发数据库应用程序的方法和过程。6.1了解MFCODBCMFC是MicrosoftFoundationClass(微软基础类库)的缩写,它的设计目标是简化开发人员的工作。MFC使开发人员创建基于Windows的应用程序,而不必掌握下层的Windows体系结构。由于数据库应用程序是管理数据的重要方面,Microsoft开发了ODBCAPI的封装程序,为ODBC编程提供了一个面向对象的方法。MFC对ODBC的封装主要是开发了CDatabase类和CRecordSet类。6.1.1CDatabase类CDatabase类用于应用程序建立同数据源的连接。CDatabase类包含一个m_hdbc变量,它代表了数据源的连接句柄。如果要建立CDatabase类的实例,应先调用该类的构造函数,再调用Open函数,通过调用,初始化环境变量,并执行与数据源的连接。关闭数据源连接的函数是Close。CDatabase类提供了对数据库进行操作的函数,为了执行事务操作,CDatabase类提供了BeginTrans函数,当全部数据都处理完成后,可以通过调用CommitTrans函数提交事务,或者在特殊情况下通过调用Rollback函数将处理回退。CDatabase类提供的函数可以用于返回数据源的特定信息,例如通过GetConnect函数返回在使用函数Open连接数据源时的连接字符串,通过调用IsOpen函数返回当前的CDatabase实例是否已经连接到数据源上,通过调用CanUpdate函数返回当前的CDatabase实例是否是可更新的,通过调用CanTransact函数返回当前的CDatabase实例是否支持事务操作,等等。总之,CDatabase类为C++数据库开发人员提供了ODBC的面向对象的编程接口。6.1.2CRecordSet类要实现对结果集的数据操作,就要用到CRecordSet类。CRecordSet类定义了从数据库接收或者发送数据到数据库的成员变量,CRecordSet类定义的记录集可以是表的所有列,也可以是其中的一列,这是由SQL语句决定的。CRecordSet类的成员变量m_hstmt代表了定义该记录集的SQL语句句柄,m_nFields第6章MFCODBC编程-113-成员变量保存了记录集中字段的个数,m_nParams成员变量保存了记录集所使用的参数个数。CRecordSet的记录集通过CDatabase实例的指针实现同数据源的连接,即CRecordSet的成员变量m_pDatabase。如果记录集使用了WHERE子句,m_strFilter成员变量将保存记录集的WHERE子句的内容,如果记录集使用了ORDERBY子句,m_strSort成员变量将保存记录集的ORDERBY子句的内容。由多种方法可以打开记录集,最常用的方法是使用Open函数执行一个SQLSELECT语句。有如下四种类型的记录集:CRecordset::dynaset:动态记录集,支持双向游标,并保持同所连接的数据源同步,对数据的更新操作可以通过一个fetch操作获取。CRecordset::snapshot:静态快照,一旦形成记录集,此后数据源的所有改变都不能体现在记录集里,应用程序必须重新进行查询,才能获取对数据的更新。该类型记录集也支持双向游标。CRecordset::dynamic:同CRecordset::dynaset记录集相比,CRecordset::dynamic记录还能在fetch操作里同步其它用户对数据的重新排序。CRecordset::forwardOnly:除了不支持逆向游标外,其它特征同CRecordset::snapshot相同。6.2MFCODBC数据库访问技术6.2.1记录查询使用CRecordSet的Open()和Requery()成员函数可以实现记录查询。需要注意的是,在使用CRecordSet的类对象之前,必须使用CRecordSet的成员函数Open()来获得有效的记录集。一旦使用过Open()函数,再次查询时使用Requery()函数就可以了。在调用Open()函数时,如果已经将一个打开的CDatabase对象指针传递给CRecordSet类对象的m_pDatabase成员变量,那么,CRecordSet类对象将使用该数据库对象建立ODBC连接;否则,如果m_pDatabase为空指针,对象就需要就新建一个CDatabase类对象并使其与缺省的数据源相连,然后进行CRecordSet类对象的初始化。缺省数据源由GetDefaultConnect()函数获得。也可以通过特定的SQL语句为CRecordSet类对象指定数据源,并以它来调用CRecordSet类的Open()函数,例如:myRS.Open(AFX_DATABASE_USE_DEFAULT,strSQL);如果没有指定参数,程序则使用缺省的SQL语句,即对在GetDefaultSQL()函数中指定的SQL语句进行操作,代码如下:第6章MFCODBC编程-114-CStringCMyRS::GetDefaultSQL(){return_T([Name],[Age]);}对于GetDefaultSQL()函数返回的表名,对应的缺省操作是SELECT语句,例如:SELECT*FROMBasicData,MainSize在查询过程中,也可以利用CRecordSet类的成员变量m_strFilter和m_strSort来执行条件查询和结果排序。m_strFilter用于指定过滤字符串,存放着SQL语句中关键字WHERE后的条件语句;m_strSort用于指定用于排序的字符串,存放着SQL语句中关键字ORDERBY后的字符串。例如:myRS.m_strFilter=Name='刘鹏';myRS.m_strSort=Age;myRS.Requery();数据库查询中对应的SQL语句为:SELECT*FROMBasicData,MainSizeWHEREName='刘鹏'ORDERBYAge除了直接赋值给成员变量m_strFilter以外,还可以通过参数化实现条件查询。利用参化可以更直观、更方便地完成条件查询任务。参数化方法的步骤如下:(1)声明参变量,代码如下:CStringstrName;intnAge;(2)在构造函数中初始化参变量如下:strName=_T();nAge=0;m_nParams=2;(3)将参变量与对应列绑定,代码如下:pFX-SetFieldType(CFieldExchange::param)RFX_Text(pFX,_T(Name),strName);RFX_Single(pFX,_T(Age),nAge);完成以上步骤之后就可以利用参变量进行条件查询了,代码如下:m_pmyRS-m_strFilter=Name=?ANDage=?;m_pmyRS-strName=刘鹏;m_pmyRS-nAge=26;m_pmyRS-Requery();参变量的值按绑定的顺序替换查询字串中的“?”通配符。如果查询的结果是多条记录,可以利用CRecordSet类的成员函数Move(),MoveNext(),MovePrev(),MoveFirst()和MoveLast()来移动记录光标。6.2.2记录添加使用AddNew()成员函数能够实现记录添加,需要注意的是,在记录添加之前必须保证数据库是以允许添加的方式打开的,代码如下:m_pmyRS-AddNew();//在表的末尾添加新记录m_pmyRS-SetFieldNull(&(m_pSet-m_type),FALSE);第6章MFCODBC编程-115-m_pmyRS-m_strName=刘鹏;//输入新的字段值m_pmyRS-m_nAge=26;//输入新的字段值m_pmyRS-Update();//将新记录存入数据库m_pmyRS-Requery();//重新建立记录集6.2.3记录删除调用Delete()成员函数能够实现记录删除,在调用Delete()函数后不需调用Update()函数,代码如下:m_pmyRS-Delete();if(!m_pmyRS-IsEOF())m_pmyRS-MoveNext();elsem_pmyRS-MoveLast();6.2.4记录修改调用Edit()成员函数可以实现记录修改,在修改完成后需要调用Update()将修改结果存入数据库,代码如下:m_pmyRS-Edit();//修改当前记录m_pmyRS-m_strName=刘波;//修改当前记录字段值...m_pmyRS-Update();//将修改结果存入数据库m_pmyRS-Requery();6.2.5撤销数据库更新操作如果用户增加或者修改记录后希望放弃当前操作,可以在调用Update()函数之前调用Move()函数,就可以使数据库更新撤销了,代码如下:CRecordSet::Move(AFX_MOVE_REFRESH);该函数用于撤消增加或修改模式,并恢复在增加或修改模式之前的当前记录。其中参数AFX_MOVE_REFRESH的值为零。6.2.6直接执行SQL语句虽然通过CRecordSet类我们可以完成大多数的数据库查询操作,而且在CRecordSet类的Open()成员函数中也可以提供SQL语句,但有的时候我们还想进行一些其他操作,例如建立新表、删除表、建立新的字段等等,这时就需要用到CDatabase类的直接执行SQL语句的机制。通过调用CDatabase类的ExecuteSQL()成员函数就能够完成QL语句的直接执行,代码如下:BOOLCMyDB::ExecuteSQLWithReport(constCString&strSQL){TRY{第6章MFCODBC编程-116-m_pMyDB-ExecuteSQL(strSQL);//直接执行SQL语句}CATCH(CDBException,e){CStringstrMsg;strMsg.LoadString(IDS_EXECUTE_SQL_FAILED);strMsg+=strSQL;returnFALSE;}END_CATCHreturnTRUE;}需要注意的是,由于不同DBMS提供的数据操作语句不尽相同,直接执行SQL语句可能会破坏软件的DBMS无关性,因此在应用中应当慎用此类操作。6.2.7MFCODBC的数据库操作过程同ODBCAPI编程类似,MFC的ODBC编程也要先建立同ODBC数据源的连接,这个过程由一个CDatabase对象的Open函数实现。然后CDatabase对象的指针将被传递到CRecordSet对象的构造函数里,使CRecordSet对象与当前建立起来的数据源连接结合起来。完成数据源连接之后,大量的数据库编程操作将集中在记录集的操作上。CRecordSet类的丰富的成员函数可以让开发人员轻松地完成基本的数据库应用程序开发任务。当然,完成了所有的操作之后,在应用程序退出运行状态的时候,需要将所有的记录集关闭,并关闭所有同数据源的连接。6.3MFCODBC编程实例6.3.1实例概述需求调查与分析某贸易公司经理需要对公司日常处理的业务通过计算机进行监控,因此需要开发一个浏览数据和报表的数据库应用软件,该软件的主要功能是数据表示和报表。数据的内容包括公司日常的销售报告、产品情况、客户情况、雇员情况以及与公司合作的运货商的情况,数据报表的主要目的是能够将浏览的信息以报表的方式打印出来。数据库系统及其访问技术在本实例里,我们采用MFC的ODBC数据库
本文标题:MFC ODBC 编程
链接地址:https://www.777doc.com/doc-6068171 .html