VisualC++数据库连接论文

时间:2022-03-20 02:12:00

导语:VisualC++数据库连接论文一文来源于网友上传,不代表本站观点,若需要原创文章可咨询客服老师,欢迎参考。

VisualC++数据库连接论文

一、开放数据库连接

ODBC(OpenDataBaseConnectivity,开放数据库连接)是微软开放服务结构中有关数据库的一个组成部分。它建立了一组规范,并提供了一组应用程序调用接口。用这样一组接口建立的应用程序,对数据库的操作不依赖于任何数据库管理系统,不直接与任何DBMS打交道,由此可实现应用程序对不同DBMS的共享论文。数据库操作的“数据源”对应用程序是透明的,所有的数据库操作由对应DBMS的ODBC驱动程序(ODBCDriver)完成。有了ODBC驱动程序,数据源就变得十分广泛,它可以是本机的某种数据库格式的文件(如本机DOS目录下的Access文

件*.mdb),也可以是远程数据库文件(如MicrosoftSQLServer);它可以是已知的某种DBMS格式,也可以是一种全新的数据库格式。总之,它取决于提供了什么数据库类型的驱动程序。

visualc++中的ODBC主要是实现基于Windows的关系数据库的应用的共享。

二、ODBC管理器

在ODBC中,数据源是一个重要的概念,它是数据库位置和数据库类型等连接信息的总和。数据源在使用前必须通过ODBC管理器(Administrator)进行登录。在登录数据源时,要搞清数据源名(Datasourcename)、数据库文件名(Databasename)和数据表格名(Tablename)这三者的概念和相互关系:数据源实际是一种数据连接的抽象,数据源名是登录时赋予的“连接”的名称,以供应用程序使用,至于该数据源下连接的是哪一个数据库,则由数据库文件名指出(如Access2.0forMSOffics中的.mdb文件);一个数据库文件中可以包括若干个数据表格(table)和其他。在关系@@09A05900.GIF;图1ODBC层次关系图数据库中,数据是以二维表格的方式存在于数据库@@文件中,应用程序最终的操作目标即是这些表格中的行(row记录)和列(columns字段)数据。对于foxprow数据源,数据库文件名是“路径名”,而该路径下的所有数据文件(*.dbf)都属于该“数据库文件”名下的数据表格(table)。

ODBC管理器被装在ControlPanel里(ODBCINST.CPL)。通过该工具可以增添、修改或删除数据源,也用来增添、删除ODBC驱动程序,ODBC管理器把数据源和它们的连接信息保存在ODBC.INI、ODBCINST.INI和ODBCISAM.INI中。当需要共享应用程序时,只需按新的数据文件的类型和位置重新登录即可。

三、ODBC应用程序接口

ODBCAPI是一组标准的ODBC函数库,除了一般的数据库操作函数外,还包括一组函数(如SQLExec或SQLExecdirect)能够内嵌标准SQL查询语句。SQL(StructuredQueryLanguage结构化查询语言)是一种存取关系型数据库的标准语言,能够定义、查询、修改和控制数据,简单的语句能够作用于整个数据表格,具有很强的功能。

同Windows3.1SDK中API类似,ODBCAPI也是基于句柄(handle)进行操作的。API函数按功能可分为以下几类:

·数据源连接函数,设置/获取有关信息的函数;

·准备/提交执行SQL查询语句的函数和获得数据的函数;

·终止函数和异常处理函数。

上述函数的顺序也表示了进行数据库操作的一般顺序。两个需要特别说明,一是数据类型问题:数据源中的数据所具有的数据类型称为SQL数据类型,这些数据类型在其数据源中可能比较特殊,不一定和ODBCSQL数据类型存储方式一致,驱动程序把这些数据类型同ODBCSQL数据类型进行相互转换,每一个ODBCSQL数据类型都相当于一个ODBCC语言数据类型;二是函数的调用级别问题,并不是每一个ODBC驱动程序都支持所有的ODBCAPI函数调用,在应用程序中,可以调用有关函数获取驱动程序以支持层次方面的信息。

四、ODBC编程

在VisualC++中,MFC(MicrosoftFoundationClass基本类库)是经过对Windows应用程序中各个部件进行类的抽象而建立的一组预定义的类,如窗口基类(CWnd)、各种窗口派生类等等,这些类在应用程序中可直接使用,不需要重新定义。在MFC中,也为ODBC预定义了几个类,其中主要的是数据库类(CDatabase)和记录集合类(CRecoredset)。这两个类既有联系又有区别,在应用程序中,可以分别使用,也可以同时使用,每一类也可以同时存在多个对象。CDatabase的每一个对象代表了一个数据源的连接,CRecordset的每一个对象代表了从一

个数据表中按预定的查询条件获得的记录的集合,一般说来,前者适宜于对数据源下的某个数据表格进行整体操作,后者用于对所选的记录集合进行处理。

同Windows类与SDKAPI函数的关系一样,CDatabase类与ODBCAPI函数也有类似的关系,但CDatabase类中并不包含所有的ODBCAPI函数,大部分操作功能仍须直接调用ODBCAPI函数,如目录功能函数,用于获得数据源下的数据表格信息,如表格名,字段名等。

在应用编程时,一般使用CDatabase和CRecordset的派生类。假设派生类分别为CUserdb和CUserset,而在应用类CUserClass中,使用了一个CUserdb对象(m-db)和一个Cuserset对象(m-recset),图2给出了用户应用类与ODBC类的相互关系示意图。

@@09A05901.GIF;图2CDatabaseCRecordset类与应用类及数据源关系图@@

1.m-db连接数据源

m-db在完成定义构造后,要调用CDatabase的打开(Open)函数以进行数据源的实际连接:

m-db.Open(lpszDSN,bExclusive,bReadOnly,lpszConnect);

打开函数需要输入四个参数。lpszDSN:要连接的数据源的名字,如果lpszDSN=NULL且lpszConnect中也没有指明数据源名,则该调用会自动出现一个对话框列出所有可用的数据源(名),让用户选择。bExclusive:只支持“假”(False)值,表示为共享(share)方式连接。因此,应用程序在运行前,一定要装入share.exe或在Windows的system.ini中装入vshare.386。ReadOnly:指明数据源操作方式是“只读”还是可以修改。lpszConnect:指明连接字符串,包括数据源名、用户标识码、口令等信息。该字符串必须以“ODBC;”开头,表示该连接是与一个ODBC数据源的连接(考虑以后版本支持非ODBC数据源)。

m-db打开后,其指针可以传给m-recset作为其数据源。m-db关闭后,将关闭所有CRecordset对它的连接,m-db也可以重新打开。

2.m-db操作数据

数据源打开后,即可对数据库文件中的数据表格进行操作,操作以调用SQL语句方式进行,可直接通过ODBCAPI函数,或者CDatabase类成员函数ExecuteSQL。数据表名在SQL语句中指定,如下语句则在所在的数据源中的clerk表中插入一个记录,记录的name字段值为"chen"。

m-db.ExecuteSQL("insertintoclerk(name)value(''''chen'''')");3.m-recset连接数据m-recset在构造时,可传入一个CDatabase对象指针,作为m-recset的数据源,当为NULL时,必须重载CRecordset的函数GetDefaultConnect,以提供数据源连接字符串(相当于m-db.Open中的lpszConnect)。如下则表示连接名为COMPANY的数据源(当传入了合法的CDatabase对象指针时,该函数将不被调用)。

CStringCUserset::GetDefaultConnect()

{

return"ODBC;DSN=COMPANY;";

}4.m-recset选取记录和字段

m-recset在调用打开函数时,即获得了符合条件的一组记录,条件语句在Open函数中的lpszSQL中给出,如果lpszSQL为NULL,则必须重载CRecordset的函数以提供该语句。该语句是一个SELECT语句,带或不带where和orderby子句(如果不带,where和Orderby的条件也可在CRecordset的两个预定义成员变量m-strFilter和m-strSort中给出)。lpszSQL也可以只是一个数据表名(table-name),也可以是对内嵌在数据库文件中的查询程序的调用语句。所选择的一系列字段名,在成员函数DoFieldExchange中由一系列RFX-函数指定。RFX-(RecordFieldExchange)函数,使字段和成员变量一一建立类型对应关系。另外,m-strFilter中也可以带变量参数(用"?"表示,如"fieldl>=?ANDfield2<=?"),参数与成员变量的对应关系也在DoFieldExchange中由RFX-函数指定(串中的"?"将被参数变量值逐一替换)。

voidCUserset::DoFieldExchange(CFieldExchange*pFX)

{

pFX->SetFieldType(CFieldExchange::outputColumn);

/*以下为字段连接*/

RFX-???(pFX,"field1",m-var1);

RFX-???(pFX,"field2",m-var2);

...

RFX-???(pFX,"fieldn",m-varn);

pFX->SetFieldType(CFieldExchange::param);

/*以下为参数连接*/

RFX-???(pFX,field1,m-param1);

RFX-???(pFX,field2,m-param2);

...

}其中,???为ODBCSQL数据类型名,如RFX-Double,RFX-Text等。

综合上述,选取记录和字段实际是由下列语句完成:

SELECTrfx-field-listFROMtable-name[WHEREm-strFilter][ORDERBYm-strSort]

字段变量和参数变量的个数一定要在调用打开函数前(如构造函数中)准确地赋值给成员变量m-nFields和m-nParams。m-recset在打开后的任何时候调用Requery()函数,将根据新的查询条件(例如修改了参数变量值)重新选取记录。

5.m-recset操作数据

记录集合生成后,其当前记录的各字段值被保存在前述的各字段变量中,如果调用CRecordset的滚动(scroll)函数,如MoveFirst(),MoveNext(),MovePrev(),MoveLast()等,字段变量的值将自动跟随“当前”记录的位置的变化而变化。IsBOF(),IsEOF()用于判别是否移动到记录的头或尾。

数据操作主要包括删除(Delete),添加(AddNew)和更改(Edit),一般流程为:

if(m-recset.CanUpdate())/*是否允许修改*/

{

if(m-db.CanTransact())/*是否支持“批”处理*/

{

m-db.BeginTrans();

m-recset.AddNew();

/*修改字段变量值*/

...

m-recset.Update();

m-mitTrans();

if(catcherror)

m-db.RollBack();

}

}

对于AddNew和Edit,修改字段变量后一定要调用函数Update(),否则更新将丢失,而Delete操作则不必进行字段值修改和调用Update()。

上述的CDatabase的四个函数是ODBC为保证数据操作的可靠性而提供的“批”处理函数,即在BeginTrans和CommitTrans之间的数据修改如果出现任何异常,可通过函数RoolBack来恢复所做的修改。

在多用户系统使用时,每一个数据源可以被多个用户的多个任务连接,不同的任务可同时修改相同的数据源。ODBC提供了两种数据表更新的同步机制(在m-recset.Open函数中指定),“静态”的(snapshot)和动态的(dynaset)。前者是一组静态的记录集合,当建立后不会改变,除了反应自己的添加/删除外,不反应别的用户的修改,除非调用了Requery重新建立。后者是一组动态的记录集合,自己或别的用户所作的修改随时反应到集合中来(当然也可用Requery重建),以保持记录与数据源的同步。在应用中,应根据需要确定使用哪一种方式。

五、结束语

从以上讨论可以看出,ODBC应用接口十分简便!再加上VisualC++中的AppWizard和ClassWizard自动生成框架代码功能,连接一个数据源,生成一个CRecordset对象,就更快捷了。

应用程序只需关心数据的处理而不必费心数据的存取,另外,另一个与ODBC有关的类CRecordView,是一个窗口类CWnd的派生类,建立在CRecordset上,可直接构造数据库记录显示窗口,某些情况下也不妨一用。