Visual C++中的开放数据库连接技术
@@09A05901.GIF;图2 CDatabase CRecordset类与应用类及数据源关系图@@
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语句方式进行,可直接通过ODBC API函数,或者CDatabase类成员函数ExecuteSQL。数据表名在SQL语句中指定,如下语句则在所在的数据源中的clerk表中插入一个记录,记录的name字段值为"chen"。
m-db.ExecuteSQL("insert into clerk(name) value('chen')");3.m-recset连接数据m-recset在构造时,可传入一个CDatabase对象指针,作为m-recset的数据源,当为NULL时,必须重载CRecordset的函数GetDefaultConnect,以提供数据源连接字符串(相当于m-db.Open中的lpszConnect)。如下则表示连接名为COMPANY的数据源(当传入了合法的CDatabase对象指针时,该函数将不被调用)。
CString CUserset::GetDefaultConnect()
{
return"ODBC;DSN=COMPANY;";
}4.m-recset选取记录和字段
m-recset在调用打开函数时,即获得了符合条件的一组记录,条件语句在Open函数中的lpszSQL中给出,如果lpszSQL为NULL,则必须重载CRecordset的函数以提供该语句。该语句是一个SELECT语句,带或不带where和order by子句(如果不带,where和Order by的条件也可在CRecordset的两个预定义成员变量m-strFilter和m-strSort中给出)。lpszSQL也可以只是一个数据表名(table-name),也可以是对内嵌在数据库文件中的查询程序的调用语句。所选择的一系列字段名,在成员函数DoFieldExchange中由一系列RFX-函数指定。RFX-(Record Field Exchange)函数,使字段和成员变量一一建立类型对应关系。另外,m-strFilter中也可以带变量参数(用"?"表示,如"fieldl>=? AND field2<=?"),参数与成员变量的对应关系也在DoFieldExchange中由RFX-函数指定(串中的"?"将被参数变量值逐一替换)。
void CUserset::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);
...
}其中,???为ODBC SQL数据类型名,如RFX-Double,RFX-Text等。
综合上述,选取记录和字段实际是由下列语句完成:
SELECT rfx-field-list FROM table-name[WHERE m-strFilter][ORDER BY m-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-db.CommitTrans();
if(catch error)
m-db.RollBack();
}
}
对于AddNew和Edit,修改字段变量后一定要调用函数Update(),否则更新将丢失,而Delete操作则不必进行字段值修改和调用Update()。
上述的CDatabase的四个函数是ODBC为保证数据操作的可靠性而提供的“批”处理函数,即在BeginTrans和CommitTrans之间的数据修改如果出现任何异常,可通过函数RoolBack来恢复所做的修改。
在多用户系统使用时,每一个数据源可以被多个用户的多个任务连接,不同的任务可同时修改相同的数据源。ODBC提供了两种数据表更新的同步机制(在m-recset.Ope
Tags:
作者:佚名评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论