VC中使用ADO的方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

VC中使⽤ADO的⽅法
ADO中打开⼀个连接:
pConnection->ConnectionString = "这⾥的字符串有下⾯四种写法"; //对连接字符串赋值
pConnection->Open(ConnectionString,"","",adModeUnknown); //连接数据库
第⼆三个参数分别为⽤户的ID与密码,因为在连接字符串ConnectionCstring中已经设置好了,这⾥可以为空。

第四个参数可以取下⾯两个参数:adAsyncConnect,异步打开数据库,在ASP中直接⽤16。

adConnectUnspecified,同步打开数据库,在ASP中直接⽤-1。

ConnectionString根据不同的数据源,分别对应不同的写法(要记下来很困难,可以在VB中利⽤ADO控件先连接好,再将其拷贝在VC中,这样不容易出错)
1)访问Access 2000
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=databaseName;User ID=userName;Password=userPassWord"
2)访问ODBC数据
"Provider=MADASQL;DSN=dsnName;UID=userName;PWD=userPassword;"
3)访问Oracle数据库
“Provider=MSDAORA;Data Sourse=serverName;User ID=userName;Password=userPassword;"
4)访问MS SQL数据库
"Provider=SQLOLEDB,Data Source=serverName;Initial Catalog=databaseName;User ID=userName;Password=userPassword;"
使⽤ADO开发应⽤程序有两种⽅法,⼀种是直接在应⽤程序中使⽤ADO数据控件,该⽅法最简单,⽆需编写⼀⾏代码即可实现对数据库的访问,另⼀种⽅法是直接使⽤ADO对象实现对数据库的操作,该⽅法较复杂,但可以让程序员更深⼊的控制数据库。

 ⼀.使⽤ActiveX控件建⽴应⽤程序
该⽅法需要两个ActiveX控件:Microsoft ADO Data Control ,version 6.0(OLE DB)和Microsoft ADO DataGrid Control ,version 6.0(OLE DB)。

下⾯我们就使⽤这两个控件,建⽴⼀个访问SQL Server 7.0数据库的应⽤程序,步骤如下:
1.启动VC6.0,使⽤MFC AppWizard建⽴⼀个单⽂档应⽤程序,命为AdoCtl,在Step1到Step 5中使⽤缺设置,直接按Next即可,在Step 6中,选择视图类的基类为CFormView,然后按Finish,按OK,⽣成应⽤程序框架;
2.在应⽤程序的ResourceView中,删除IDD_ADOCTL_FORM对话框中⾃动⽣成的静态⽂本,然后在该对话框的编辑窗⼝中击⿏标右键,在弹出的快捷菜单中选择Insert ActiveX Control...命令;
3.在接下来的Insert ActiveX Control对话框中选择Microsoft ADO Data Control ,version 6.0(OLE DB),按OK,就可以将该控件插⼊到对话框中。

4.重复步骤2、3,在对话框中插⼊Microsoft ADO DataGrid Control ,version 6.0(OLE DB)控件;
5.选中Data控件,击右键,设置该控件的属性;
6.选择Control页⾯,该属性页要连接的数据源,其中提供了3种连接数据源的⽅法:
a.使⽤数据连接⽂件(Use Data Link File);
b.使⽤ODBC数据源(Use ODBC Data Source Name);
c.使⽤连接字符串(Use Connection String).。

在本程序中,我们使⽤连接字符串,连接SQL Server7.0数据库。

连接字符串中包含了程序与数据源的连接信息,其形式为
Argument=Value,每个连接字符串可以包含多个Argument=Value表达式,不同的表达式之间以分号间隔,如访问SFJ55.MDB数据库的连接字符串可以写成如下形式:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=e:\\sfj55.mdb
ADO⽀持如下的四种连接字符串的属性设置:
选择Use Connection String选项,按Build...钮,在数据链接属性对话框中选择OLE DB Provider(OLE DB提供者),此处我们选择Microsoft OLE DB Provider for SQL Server,按下⼀步;
7.在连接属性页中输⼊服务器名称,笔者使⽤NT⼯作站,名称为BUILDER,SQL Server装在本机,故此处服务器名称为BUILDER,再选择使⽤Windows NT集成安全设置,在服务器上选择数据库,笔者选择DcProduct,这是⼀个存放⽣产明细的数据库。

测试连接成功后按确定。

也可以选择SQL Server 7.0⾃带的其他数据库和数据表。

8.选择Data控件属性的RecordSource属性页,其中Command Type 中有4个选项:
对于SQL语句和数据表名,使⽤过Access97的读者⼀定很熟悉,⾄于存储过程的有关信息请参考SQL Server的有关书籍。

此处我们选
择2-adCmdTable,表名选择[SFJ55-27-00-000MX](注意在表名两边加中括号),关闭属性对话框。

Data控件属性设置完毕;
9.选择DataGrid控件,击右键,设置该控件的属性;
10.选择All属性页,设置DataSource属性,设置为Data控件的ID号,即IDC_ADODC1,关闭属性对话框;
11.编译并运⾏应⽤程序,即可在DataGrid控件中显⽰数据表SFJ55-27-00-000MX中的数据。

到此为⽌,我们在VC6.0中使⽤ADO技术建⽴的最简单的应⽤程序已经完成,整个过程中没有编写⼀⾏代码。

只是该程序只能浏览和修改数据,不能对记录进⾏添加和删除。

如果想增加充⾜添加和删除记录的功能,在DataGrid控件的All属性页中,设置AllowAddNew和AllowDelete属性为TRUE。

这中⽅法尽管简单,但是对数据库的访问效率较低,使⽤起来也不灵活,程序员对数据库的控制较少,不能最⼤限度的发挥ADO技术⾼速灵活的特点。

下⾯通过⼀个实例来介绍在VC6.0中使⽤ADO对象访问SQL Server数据库。

⼆.使⽤ADO对象建⽴数据库应⽤程序
在VC中使⽤过DAO的读者对于CDaoWorkspace,CDaoDatabase,CDaoRecordset,CDaoTableDef等MFC类应该⾮常熟悉,然⽽,遗憾的是VC中并没有提供有关ADO对象的类,那么我们将怎样使⽤ADO对象呢?实际上,这可以通过在应⽤程序中使⽤预编译指令
#import来引⼊相关类的指针。

在使⽤ADO对象之前必须⾸先在程序中加⼊如下的代码:
#define INITGUID //定义有关的变量
#import "C:\program files\common files\system\ado\msado15.dll"rename_namespace("ADOCG")rename("EOF","EndOfFile") //引⼊动态链接库
using namespace ADOCG;
#include "icrsint.h" //包含头⽂件
以上代码在程序的运⾏过程中将产⽣名为msado15.tlh的头⽂件,该头⽂件中定义了⼀些有⽤的智能指针,以下是该⽂件关于智能指针定义的⼀段代码:
//
// Smart pointer typedef declarations
//
......
_COM_SMARTPTR_TYPEDEF(Properties, __uuidof(Properties));
_COM_SMARTPTR_TYPEDEF(Property, __uuidof(Property));
_COM_SMARTPTR_TYPEDEF(Error, __uuidof(Error));
_COM_SMARTPTR_TYPEDEF(Errors, __uuidof(Errors));
_COM_SMARTPTR_TYPEDEF(_Connection, __uuidof(_Connection));
_COM_SMARTPTR_TYPEDEF(_Recordset, __uuidof(_Recordset));
_COM_SMARTPTR_TYPEDEF(Fields, __uuidof(Fields));
_COM_SMARTPTR_TYPEDEF(Field, __uuidof(Field));
_COM_SMARTPTR_TYPEDEF(_Parameter, __uuidof(_Parameter));
_COM_SMARTPTR_TYPEDEF(Parameters, __uuidof(Parameters));
_COM_SMARTPTR_TYPEDEF(_Command, __uuidof(_Command));
......
这是基于ADO的⽀持类_com_ptr_t的⼀些指针的定义,其中宏_COM_SMARTPTR_TYPEDEF()在VC6.0头⽂件COMDEF.H中定义。

下⾯是我们经常使⽤的⼏个智能指针:
_ConnectionPtr 连接对象指针
_RecordsetPtr 记录集对象指针
_ParameterPtr 参数对象指针
_CommandPtr 命令对象指针
FieldPtr 域对象指针
PropertyPtr 属性对象指针
ErrorPtr 错误对象指针
下⾯在⼀个程序实例中说明这些指针的⽤法,程序访问的数据库为SQL Server 7.0中⾃带的NothWind,数据表名为Employees,这⾥只访问EmployeeID,LastName,FirstName,Title等4个字段:
步骤1.启动VC6.0,使⽤MFC AppWizard建⽴⼀个单⽂档应⽤程序,命为AdoCls,在Step1到Step 5中使⽤缺设置,直接按Next即可,在Step 6中,选择视图类的基类为CFormView,然后按Finish,按OK,⽣成应⽤程序框架,在应⽤程序的ResourceView中,删除
IDD_ADOCLS_FORM对话框中⾃动⽣成的静态⽂本;
步骤2.新建⼀个⽂本⽂件,并在其中输⼊如下内容,然后将其保存为MyData.h,再将其添加到AdoCls⼯程中(菜单命令:Project\Add To Project\Files...),输⼊内容如下:
//MyData.h
#define INITGUID
#import "C:\program files\common files\system\ado\msado15.dll"rename_namespace("ADOCG")rename("EOF","EndOfFile")
using namespace ADOCG;
#include "icrsint.h"
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CMyRecord : public CADORecordBinding
{
BEGIN_ADO_BINDING(CMyRecord ) //开始数据捆绑
ADO_FIXED_LENGTH_ENTRY(1,adInteger,m_id,lid,TRUE);
ADO_VARIABLE_LENGTH_ENTRY2(2,adVarChar,m_lastname,sizeof(m_lastname),llastname,TRUE)
ADO_VARIABLE_LENGTH_ENTRY2(3,adVarChar,m_firstname,sizeof(m_firstname),lfirstname,TRUE)
ADO_VARIABLE_LENGTH_ENTRY2(4,adVarChar,m_title,sizeof(m_title),ltitle,TRUE)
END_ADO_BINDING() //结束数据捆绑
public:
long m_id;
ULONG lid;
char m_lastname[20];
ULONG llastname;
char m_firstname[10];
ULONG lfirstname;
char m_title[30];
ULONG ltitle;
};
在MyData.h头⽂件中定义了⼀个CMyRecord类,该类的基类必须是CADORecordBinding,且没有构造函数和析构函数,只有⼀组⽤于数据捆绑和映射的宏和⼀组变量。

其中以“m_”开头的4个变量分别对应数据表Employees中EmployeeID,LastName,FirstName,Title等4个字段,它们将⽤于存取这4个字段的实际值,以“l”开头的4个ULONG类型的变量是对应字段的状态值,⽤于判断数据的捆绑是否成功,后⾯的程序代码中将看到其应⽤。

⽤于数据捆绑和映射的宏在头⽂件icrsint.h中定义,数据的捆绑和映射主要⽤到如下的⼏个宏:
(1). BEGIN_ADO_BINDING ()和 END_ADO_BINDING()
BEGIN_ADO_BINDING()宏的参数是⽤户⾃定义的⽤于数据捆绑的记录集类,本例中为CMyRecord。

END_ADO_BINDING()宏不带参数。

(2). ADO_FIXED_LENGTH_ENTRY()宏,该宏⽤于数据库中所有长度固定的字段,如Date/Time,BOOL,int,或定长的字符型字段。

有两个版本:
(1)#define ADO_FIXED_LENGTH_ENTRY(Ordinal,DataType,Buffer,Status,Modify);
(2)#define ADO_FIXED_LENGTH_ENTRY2(Ordinal,DataType,Buffer,,Modify);
(3). ADO_NUMERIC_ENTRY(),⽤于数值型字段。

也有两个版本:
(1)#define ADO_NUMERIC_ENTRY(Ordinal,DataType,Buffer,Precision,Scale,Status,Modify);
(2)#define ADO_NUMERIC_ENTRY(Ordinal,DataType,Buffer,Precision,Scale,Modify);
(4).ADO_VARIABLE_LENGTH_ENTRY(),有四个版本:
(1)#define ADO_VARIABLE_LENGTH_ENTRY(Ordinal,DataType,Buffer,Size,Status,Length,Modify);
(2)#define ADO_VARIABLE_LENGTH_ENTRY2(Ordinal,DataType,Buffer,Size,Status,Modify);
(3)#define ADO_VARIABLE_LENGTH_ENTRY3(Ordinal,DataType,Buffer,Size,Length,Modify);
(4)#define ADO_VARIABLE_LENGTH_ENTRY4(Ordinal,DataType,Buffer,Size,Modify);
Ordinal 被访问的记录集中的字段的序号,数据表Employees中EmployeeID,LastName,FirstName,Title等4个字段的序号分别为1、2、3、4;
DataType 字段数据类型,见头⽂件msado15.tlh(在程序的运⾏过程中将产⽣);
Buffer 字段中的值所要映射到的变量
Status 被映射字段的状态值
Modify 是否允许修改
Precision 字段值的精度(数值型)
Scale 字段值的数值范围(数值型)
Size 变长度字段值的长度(如:字符串)
步骤3.进⼊ResourceView,在IDD_ADOCLS_FORM对话框中添加如下图所⽰⼏个控件:
4个⽂本框控件对应的变量分别是m_id,m_firstname,m_lastname,m_title,这4个变量均属于CAdoClsView类。

步骤4.在CAdoClsDoc类头⽂件包含MyRecord.h,并在其中添加如下⼏个私有成员变量:
private:
CMyRecord m_rsRecSet;
_RecordsetPtr m_pRs;
IADORecordBinding * m_piAdoRecordBinding;
CString m_strCmdText;
CString m_strConnection;
HRESULT hr;
步骤5.在⽂档类构造函数中初始化COM环境和建⽴与数据库的连接,在析构函数中清除COM环境和释放有关变量。

在CAdoClsDoc类构造函数中添加如下内容:
::CoInitialize(NULL);//初始化COM环境
m_piAdoRecordBinding=NULL;
m_strConnection=_T("Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Northwind;Data Source=BUILDER");
m_strCmdText=_T("select EmployeeID,LastName,FirstName,Title from Employees");
//创建对象实例
m_pRs.CreateInstance(__uuidof(Recordset));
//利⽤智能指针打开记录集
m_pRs->Open(LPCTSTR(m_strCmdText),LPCTSTR(m_strConnection),adOpenDynamic,adLockOptimistic,adCmdText);
hr=m_pRs->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&m_piAdoRecordBinding);
hr=m_piAdoRecordBinding->BindToRecordset(&m_rsRecSet);//与CMyRecord记录类捆绑
//此处,变量hr仅仅是⽤来判函数的调⽤是否成功,如果成功则hr等于0,否则hr⼩于0。

在CAdoClsDoc类析构函数中添加如下内容:
//在析构函数中关闭与数据源的连接,释放有关变量
if(m_pRs)m_pRs->Close();
if(m_piAdoRecordBinding)m_piAdoRecordBinding->Release();
m_pRs=NULL;
CoUninitialize();//清除COM环境
注意:在ADO中,获得记录集的⽅法有⼤约3种:1.通过连接对象的Execute()⽅法;2.通过命令对象的Execute()⽅法(但是,该命令对象必须⾸先与连接对象建⽴关联pCmd->ActiveConnection=);3.直接建⽴并打开记录集对象(在这种⽅法⾥⾯,其Open()函数中的ActiveConnection参数既可以是连接对象指针,⼜可以是连接字符串)。

因此,使⽤ADO技术访问数据库的数据是⾮常⾃由的,不象DAO,必须先建⽴Database对象,然后再建⽴Recordset对象。

我们这⾥采⽤第3中⽅法,这种⽅法只适⽤与简单的应⽤中,如果在应⽤中需要访问多哥数据源,则必须采⽤1和2两种⽅法显式的建⽴连接,以加快访问速度。

步骤6.在⽂档类中添加记录集的Move类函数,MoveFirst()、MovePrevious()、MoveNext()、MoveLast()、AddNew()、CreateBlankRecord():
void CAdoClsDoc::MoveFirst()
{
if(m_pRs->Supports(adUpdate))
hr=m_piAdoRecordBinding->Update(&m_rsRecSet);
m_pRs->MoveFirst();
}
void CAdoClsDoc::MovePrevious()
{
if(!m_pRs->BOF)
{
hr=m_piAdoRecordBinding->Update(&m_rsRecSet);
m_pRs->MovePrevious();
}
}
void CAdoClsDoc::MoveNext()
{
if(!m_pRs->EndOfFile){
hr=m_piAdoRecordBinding->Update(&m_rsRecSet);
m_pRs->MoveNext();
}
}
void CAdoClsDoc::MoveLast()
{
hr=m_piAdoRecordBinding->Update(&m_rsRecSet);
m_pRs->MoveLast();
}
步骤7.在CAdoClsDoc类中添加GetMyRecord()函数:
CMyRecord * CAdoClsDoc::GetMyRecord()
{
return(&m_rsRecSet);
}
步骤8.在void CAdoClsView::OnInitialUpdate()函数中添加如下代码:
{.......
RefreshBoundData();}
步骤9.在CAdoClsView类中添加RefreshBoundData()函数及其实现代码:
void CAdoClsView::RefreshBoundData()
{
CMyRecord * pRs;
pRs=GetDocument()->GetMyRecord();
m_firstname=adFldOK==pRs->lfirstname?pRs->m_firstname:"";
m_lastname=adFldOK==pRs->llastname?pRs->m_lastname:"";
m_title=adFldOK==pRs->ltitle?pRs->m_title:"";
UpdateData(FALSE);
}
步骤10.在CAdoClsView类中添加UpdateBoundData()函数及其实现代码:
void CAdoClsView::UpdateBoundData()
{
CMyRecord * pRs;
pRs=GetDocument()->GetMyRecord();
UpdateData(TRUE);
if(pRs->m_id!=m_id)
pRs->m_id=m_id;
if(pRs->m_firstname!=m_firstname)
strcpy(pRs->m_firstname,LPCTSTR(m_firstname));
if(pRs->m_lastname != m_lastname)
strcpy(pRs->m_lastname,LPCTSTR(m_lastname));
if(pRs->m_title !=m_title)
strcpy(pRs->m_title ,LPCTSTR(m_title));
}
步骤10.在CAdoClsView类中添加IDD_ADOCLS_FORM对话框中四个按钮对应的消息映射函数:
void CAdoClsView::OnButtonFirst()
{ UpdateBoundData();
GetDocument()->MoveFirst ();
RefreshBoundData();
}
void CAdoClsView::OnButtonLast()
{ UpdateBoundData();
GetDocument()->MoveLast ();
RefreshBoundData();
}
void CAdoClsView::OnButtonNext()
{ UpdateBoundData();
GetDocument()->MoveNext ();
RefreshBoundData();
}
void CAdoClsView::OnButtonPrevious()
{ UpdateBoundData();
GetDocument()->MovePrevious ();
RefreshBoundData();
}
步骤11.编译运⾏该应⽤程序,即可实现对数据库的浏览。

使⽤ADO在VC6中建⽴数据库应⽤程序,⾄此结束,关于这⼀⽅法以及本程序例⼦,作以下⼏点说明:
1.运⾏上⾯的程序,试着改变数据库中的某个列的数值,读者将会发现,在数据记录的移动时,数据库并没有被更新。

这是因为本程序所涉及到的四个字段中,其中有⼀个标识列,EmployeeID,标识列具有⾃动增长的特性,⽤户不能更新,否则将出错,这时,语句
hr=m_piAdoRecordBinding->Update(&m_rsRecSet);将返回⼀个负值,即hr<0,读者可以SQL Server 7中的Enterprise Manager打开NothWind数据库,修改其中的数据表Employees,在该表的设计视图中将其EmployeeID所在⾏的Identify复选框取消,然后保存。

这时⽤户即可实现对数据库的更新。

在调试时注意⼀下语句hr=m_piAdoRecordBinding->Update(&m_rsRecSet),hr将等于0。

2.CMyRecord类的基类是CADORecordBinding,IADORecordBinding 是CADORecordBinding类的⼀个COM接⼝,它也是记录集类CADORecordBinding的⼀部分,⽤户可以通过该接⼝实现数据的捆绑、更新和添加,它对应3个(仅有3个)函数:BindToRecordset()、AddNew()和Update(),这三个函数可以参见头⽂件icrsint.h。

其中BindToRecordset()和Update()我们已经使⽤过,AddNew()的⽤法与Update()很相似,⾸先,将MyRecord类中各个数值变量(以m_开头)赋初值,然后调⽤
m_piAdoRecordBinding->AddNew(&m_rsRecSet)和m_pRs->MoveLast()(将记录指针移到新添加的空⽩记录处),即可实现记录的添加功能。

3.在宏ADO_VARIABLE_LENGTH_ENTRY2(Ordinal,DataType,Buffer,Size,Status,Modify);中,第⼀个参数Ordinal指的是在当前记录集中字段的位置,⽽不是原数据表中该字段的位置。

如本程序中的LastName字段,在程序中所要访问的记录集中的位置是2,如果将记录集改为:“select LastName,FirstName,Title from Employees”,则LastName的位置将为1,Ordinal=1。

4.如果读者不喜欢数据捆绑的⽅式访问数据库,ADO提供了对记录集中单个域进⾏访问的⽅法,如以下代码可以更新当前记录中的FirstName字段:
_variant_t vFld,vValue;
vFld.SetString("FirstName");
vValue.SetString("Rose Tom");
m_pRs->Update(vFld,vValue);
以下代码可以取得FirstName字段值:
_variant_t vValue;
CString strValue;
vValue=m_pRs->GetCollect(_variant_t ("FirstName"));
vValue.ChangeType(VT_BSTR);
strValue=vValue.bstrVal;
这种直接访问字段值的⽅法很灵活,缺点是编程⼈员必须频繁的调⽤ChangeType函数进⾏数据类型的转换。

相关文档
最新文档