VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
2014-02-09 10:29
901 查看
1.首先,要用#import语句来引用支持ADO的组件类型库(*.tlb),其中类型库可以作为可执行程序 (DLL、EXE等)的一部分被定位在其自身程序中的附属资源里,如:被定位在msado15.dll的附属资源中,只需要直接用 #import引用它既可。可以直接在Stdafx.h文件中加入下面语句来实现:
[cpp] view plaincopy
#import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename("EOF", "adoEOF")
【注意,在MFC中路径要用"/"或者"//"】
其中路径名可以根据自己系统安装的ADO支持文件的路径来自
行设定。当编译器遇到#import语句时,它会为引用组件类型库中的接口生成包装类,#import语句实际上相当于执行了API涵数
LoadTypeLib()。#import语句会在工程可执行程序输出目录中产生两个文件,分别为*.tlh(类型库头文件)及*.tli(类型库实现
文件),它们分别为每一个接口产生智能指针,并为各种接口方法、枚举类型,CLSID等进行声明,创建一系列包装方法。语句no_namespace说明
ADO对象不使用命名空间,rename ("EOF",
"adoEOF")说明将ADO中结束标志EOF改为adoEOF,以避免和其它库中命名相冲突。
2.其次,在程序初始过程中需要初始化组件,一般可以用CoInitialize(NULL);来实现,这种方法在结束时要关闭初始化的COM,可以用下
面语句CoUnInitialize();来实现。在MFC中还可以采用另一种方法来实现初始化COM,这种方法只需要一条语句便可以自动为我们实现初始
化COM和结束时关闭COM的操作,语句如下所示:
[cpp] view plaincopy
AfxOleInit();
3.接着,就可以直接使用ADO的操作了。我们经常使用的只是前面用#import语句引用类型库时,生成的包装类.tlh中声明的智能指针中的三个,它
们分别是_ConnectionPtr、_RecordsetPtr和_CommandPtr。下面分别对它们的使用方法进行介绍:
_ConnectionPtr接
口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。使用
_ConnectionPtr接口返回一个记录集不是一个好的使用方法。对于要返回记录的操作通常用_RecordserPtr来实现。而用
_ConnectionPtr操作时要想得到记录条数得遍历所有记录,而用_RecordserPtr时不需要。
_CommandPtr接
口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,你可以利用全局
_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据访问操作,后者是比较好的选择。但
如果你要频繁访问数据库,并要返回很多记录集,那么,你应该使用全局_ConnectionPtr接口创建一个数据连接,然后使用_CommandPtr
接口执行存储过程和SQL语句。
_RecordsetPtr是一
个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定,游标控制等。同_CommandPtr接口一样,它不一定要使用一个已
经创建的数据连接,可以用一个连接串代替连接指针赋给
_RecordsetPtr的connection成员变量,让它自己创建数据连接。如果你要使用多个记录集,最好的方法是同Command对象一样使用
已经创建了数据连接的全局_ConnectionPtr接口,然后使用_RecordsetPtr执行存储过程和SQL语句。
特别声明:如果是MFC程序,则初始化ado组件就不需要用CoInitialize(NULL), 只需要在**App::InitInstance()函数中调用AfxOleInit();即可:例如:
[cpp] view plaincopy
BOOL CMyAdoTestApp::InitInstance()
{
if(!AfxOleInit())//这就是初始化COM库
{
AfxMessageBox(“OLE初始化出错!”);
return FALSE;
}
创建一个对话框程序。新建一个名为ADOConn的类,在头文件中导入msado15.dll
语句如下:
[cpp] view plaincopy
#import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace
rename("EOF","adoEOF")rename("BOF","adoBOF")
这句话主要作用是引入ADO类库。
1:在ADOConn.h头文件中为类添加变量和初始化函数
[cpp] view plaincopy
//添加一个指向Connection的指针
_ConnectionPtr m_pConnection;
//添加一个指向Recordset对象的指针
_RecordsetPtr m_pRecordset;
void ADOConn::OnInitADOConn()
{
//初始化OLE/COM库环境
::CoInitialize(NULL);
try
{
//´创建connection连接对象
m_pConnection.CreateInstance("ADODB.Connection");
//设置连接字符串
_bstr_t strConnect="Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security
Info=False;Initial Catalog=data;Data Source=.";
//SERVER和UID,PWD的设定需要根据自己的情况
m_pConnection->Open(strConnect,"","",adModeUnknown);
}
//捕捉异常
catch(_com_error e)
{
//显示错误信息
AfxMessageBox(e.Description());
}
}
2:为ADOConn类添加GetRecordSet的函数,目的是打开并获得记录集,代码如下:
[cpp] view plaincopy
_RecordsetPtr& ADOConn::GetRecordSet(_bstr_t bstrSQL)
{
try
{
//连接数据库,如果connection为空则重新连接
if(m_pConnection==NULL)
OnInitADOConn();
//创建记录集对象
m_pRecordset.CreateInstance(__uuidof(Recordset));
//取得表中的记录
m_pRecordset->Open(bstrSQL,m_pConnection.GetInterfacePtr(),
adOpenDynamic,adLockOptimistic,adCmdText);
}
catch(_com_error e)
{
e.Description();
}
//返回记录集
return m_pRecordset;
}
3:在ADOConn类中添加ExecteSQL函数,目的是用来执行SQL语句,代码如下:
[cpp] view plaincopy
BOOL ADOConn::ExecuteSQL(_bstr_t bstrSQL)
{
_variant_t RecordsAffected;
try
{
//是否连接上数据库
if(m_pConnection==NULL)
OnInitADOConn();
m_pConnection->Execute(bstrSQL,NULL,adCmdText);//adCmdText文本命令
return true;
}
catch(_com_error e)
{
e.Description();
return false;
}
}
4:设置退出记录集类
[cpp] view plaincopy
void ADOConn::ExitConnect()
{
//关闭记录集和连接
if(m_pRecordset!=NULL)
m_pRecordset->Close();
m_pConnection->Close();
}
5:为对话框添加一个ListControl控件按钮,并设置属性为Report
为ListControl控件关联一个对象CListCtrl m_grid;
在初始化对话框函数里面添加
[cpp] view plaincopy
//设置ListControl控件的风格
m_grid.SetExtendedStyle(LVS_EX_FLATSB
|LVS_EX_FULLROWSELECT
|LVS_EX_HEADERDRAGDROP
|LVS_EX_ONECLICKACTIVATE
|LVS_EX_GRIDLINES);
m_grid.InsertColumn(0,"编号",LVCFMT_LEFT,100,0);
m_grid.InsertColumn(1,"姓名",LVCFMT_LEFT,100,1);
m_grid.InsertColumn(2,"性别",LVCFMT_LEFT,100,2);
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
CString sql;
sql.Format("select* from employees order by 编号 desc");
_RecordsetPtr m_pRecordset;
m_pRecordset = m_AdoConn.GetRecordSet((_bstr_t)sql);
while(m_AdoConn.m_pRecordset->adoEOF==0)//EOF判断是否到末尾
{
m_grid.InsertItem(0,"");
m_grid.SetItemText(0,0,(char*)(_bstr_t)m_pRecordset->GetCollect("编号"));
m_grid.SetItemText(0,1,(char*)(_bstr_t)m_pRecordset->GetCollect("姓名"));
m_grid.SetItemText(0,2,(char*)(_bstr_t)m_pRecordset->GetCollect("性别"));
m_pRecordset->MoveNext();
}
m_AdoConn.ExitConnect();//断开数据库连接
6:添加数据.
在对话框添加两个EditBox控件和一个Combox控件和一个按钮控件
如下图:
关联对象如下
[cpp] view plaincopy
CString m_id,m_name;CComboBox m_combo;
//在初始化中添加
m_combo.InsertString(0,"男");
m_combo.InsertString(1,"女");
m_combo.SetCurSel(0);
//按钮响应事件:
UpdateData(true);
if(m_id.IsEmpty())
{
MessageBox("编号不能为空");
return;
}
if(m_name.IsEmpty())
{
MessageBox("姓名不能为空");
return;
}
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
_bstr_t sql;
sql = "select*from employees";
_RecordsetPtr m_pRecordset;
m_pRecordset=m_AdoConn.GetRecordSet(sql);
CString sex;
m_combo.GetLBText(m_combo.GetCurSel(),sex);
try
{
m_pRecordset->AddNew();//添加新行
m_pRecordset->PutCollect("编号",(_bstr_t)m_id);
m_pRecordset->PutCollect("姓名",(_bstr_t)m_name);
m_pRecordset->PutCollect("性别",(_bstr_t)sex);
m_AdoConn.ExitConnect();
}
catch(...)
{
MessageBox("操作失败");
return;
}
MessageBox("保存成功");
m_grid.DeleteAllItems();
AddToGrid();//这个是用来显示数据的,就是第八步初始化中的代码
7 修改记录集
在添加一个EditBox控件,关联对象CString m_old;用来保存,修改之前的编号;
添加修改按钮,并响应事件,代码如下:
[cpp] view plaincopy
UpdateData(true);
if(m_name.IsEmpty())
{
MessageBox("姓名不能为空");
return;
}
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
_bstr_t sql;
sql = "select*from employees";
_RecordsetPtr m_pRecordset;
m_pRecordset=m_AdoConn.GetRecordSet(sql);
CString sex;
m_combo.GetLBText(m_combo.GetCurSel(),sex);
try
{
m_pRecordset->Move((long)pos,vtMissing);
m_pRecordset->PutCollect("编号",(_bstr_t)m_id);
m_pRecordset->PutCollect("姓名",(_bstr_t)m_name);
m_pRecordset->PutCollect("性别",(_bstr_t)sex);
m_pRecordset->Update();
m_AdoConn.ExitConnect();
}
catch(...)
{
MessageBox("操作失败");
return;
}
MessageBox("操作成功");
m_grid.DeleteAllItems();
AddToGrid();
8:删除记录集
UpdateData(true);
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
_bstr_t sql;
sql = "select*from employees";
_RecordsetPtr m_pRecordset;
m_pRecordset=m_AdoConn.GetRecordSet(sql);
CString m_id;
try
{
m_pRecordset->Move(pos,vtMissing);
m_pRecordset->Delete(adAffectCurrent);
m_pRecordset->Update();
m_AdoConn.ExitConnect();
}
catch(...)
{
MessageBox("操作失败");
return;
}
MessageBox("删除成功.");
m_grid.DeleteAllItems();
AddToGrid();
以上总结了,SQL连接四种基本操作
[cpp] view plaincopy
#import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename("EOF", "adoEOF")
【注意,在MFC中路径要用"/"或者"//"】
其中路径名可以根据自己系统安装的ADO支持文件的路径来自
行设定。当编译器遇到#import语句时,它会为引用组件类型库中的接口生成包装类,#import语句实际上相当于执行了API涵数
LoadTypeLib()。#import语句会在工程可执行程序输出目录中产生两个文件,分别为*.tlh(类型库头文件)及*.tli(类型库实现
文件),它们分别为每一个接口产生智能指针,并为各种接口方法、枚举类型,CLSID等进行声明,创建一系列包装方法。语句no_namespace说明
ADO对象不使用命名空间,rename ("EOF",
"adoEOF")说明将ADO中结束标志EOF改为adoEOF,以避免和其它库中命名相冲突。
2.其次,在程序初始过程中需要初始化组件,一般可以用CoInitialize(NULL);来实现,这种方法在结束时要关闭初始化的COM,可以用下
面语句CoUnInitialize();来实现。在MFC中还可以采用另一种方法来实现初始化COM,这种方法只需要一条语句便可以自动为我们实现初始
化COM和结束时关闭COM的操作,语句如下所示:
[cpp] view plaincopy
AfxOleInit();
3.接着,就可以直接使用ADO的操作了。我们经常使用的只是前面用#import语句引用类型库时,生成的包装类.tlh中声明的智能指针中的三个,它
们分别是_ConnectionPtr、_RecordsetPtr和_CommandPtr。下面分别对它们的使用方法进行介绍:
_ConnectionPtr接
口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。使用
_ConnectionPtr接口返回一个记录集不是一个好的使用方法。对于要返回记录的操作通常用_RecordserPtr来实现。而用
_ConnectionPtr操作时要想得到记录条数得遍历所有记录,而用_RecordserPtr时不需要。
_CommandPtr接
口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,你可以利用全局
_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据访问操作,后者是比较好的选择。但
如果你要频繁访问数据库,并要返回很多记录集,那么,你应该使用全局_ConnectionPtr接口创建一个数据连接,然后使用_CommandPtr
接口执行存储过程和SQL语句。
_RecordsetPtr是一
个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定,游标控制等。同_CommandPtr接口一样,它不一定要使用一个已
经创建的数据连接,可以用一个连接串代替连接指针赋给
_RecordsetPtr的connection成员变量,让它自己创建数据连接。如果你要使用多个记录集,最好的方法是同Command对象一样使用
已经创建了数据连接的全局_ConnectionPtr接口,然后使用_RecordsetPtr执行存储过程和SQL语句。
特别声明:如果是MFC程序,则初始化ado组件就不需要用CoInitialize(NULL), 只需要在**App::InitInstance()函数中调用AfxOleInit();即可:例如:
[cpp] view plaincopy
BOOL CMyAdoTestApp::InitInstance()
{
if(!AfxOleInit())//这就是初始化COM库
{
AfxMessageBox(“OLE初始化出错!”);
return FALSE;
}
创建一个对话框程序。新建一个名为ADOConn的类,在头文件中导入msado15.dll
语句如下:
[cpp] view plaincopy
#import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace
rename("EOF","adoEOF")rename("BOF","adoBOF")
这句话主要作用是引入ADO类库。
1:在ADOConn.h头文件中为类添加变量和初始化函数
[cpp] view plaincopy
//添加一个指向Connection的指针
_ConnectionPtr m_pConnection;
//添加一个指向Recordset对象的指针
_RecordsetPtr m_pRecordset;
void ADOConn::OnInitADOConn()
{
//初始化OLE/COM库环境
::CoInitialize(NULL);
try
{
//´创建connection连接对象
m_pConnection.CreateInstance("ADODB.Connection");
//设置连接字符串
_bstr_t strConnect="Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security
Info=False;Initial Catalog=data;Data Source=.";
//SERVER和UID,PWD的设定需要根据自己的情况
m_pConnection->Open(strConnect,"","",adModeUnknown);
}
//捕捉异常
catch(_com_error e)
{
//显示错误信息
AfxMessageBox(e.Description());
}
}
2:为ADOConn类添加GetRecordSet的函数,目的是打开并获得记录集,代码如下:
[cpp] view plaincopy
_RecordsetPtr& ADOConn::GetRecordSet(_bstr_t bstrSQL)
{
try
{
//连接数据库,如果connection为空则重新连接
if(m_pConnection==NULL)
OnInitADOConn();
//创建记录集对象
m_pRecordset.CreateInstance(__uuidof(Recordset));
//取得表中的记录
m_pRecordset->Open(bstrSQL,m_pConnection.GetInterfacePtr(),
adOpenDynamic,adLockOptimistic,adCmdText);
}
catch(_com_error e)
{
e.Description();
}
//返回记录集
return m_pRecordset;
}
3:在ADOConn类中添加ExecteSQL函数,目的是用来执行SQL语句,代码如下:
[cpp] view plaincopy
BOOL ADOConn::ExecuteSQL(_bstr_t bstrSQL)
{
_variant_t RecordsAffected;
try
{
//是否连接上数据库
if(m_pConnection==NULL)
OnInitADOConn();
m_pConnection->Execute(bstrSQL,NULL,adCmdText);//adCmdText文本命令
return true;
}
catch(_com_error e)
{
e.Description();
return false;
}
}
4:设置退出记录集类
[cpp] view plaincopy
void ADOConn::ExitConnect()
{
//关闭记录集和连接
if(m_pRecordset!=NULL)
m_pRecordset->Close();
m_pConnection->Close();
}
5:为对话框添加一个ListControl控件按钮,并设置属性为Report
为ListControl控件关联一个对象CListCtrl m_grid;
在初始化对话框函数里面添加
[cpp] view plaincopy
//设置ListControl控件的风格
m_grid.SetExtendedStyle(LVS_EX_FLATSB
|LVS_EX_FULLROWSELECT
|LVS_EX_HEADERDRAGDROP
|LVS_EX_ONECLICKACTIVATE
|LVS_EX_GRIDLINES);
m_grid.InsertColumn(0,"编号",LVCFMT_LEFT,100,0);
m_grid.InsertColumn(1,"姓名",LVCFMT_LEFT,100,1);
m_grid.InsertColumn(2,"性别",LVCFMT_LEFT,100,2);
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
CString sql;
sql.Format("select* from employees order by 编号 desc");
_RecordsetPtr m_pRecordset;
m_pRecordset = m_AdoConn.GetRecordSet((_bstr_t)sql);
while(m_AdoConn.m_pRecordset->adoEOF==0)//EOF判断是否到末尾
{
m_grid.InsertItem(0,"");
m_grid.SetItemText(0,0,(char*)(_bstr_t)m_pRecordset->GetCollect("编号"));
m_grid.SetItemText(0,1,(char*)(_bstr_t)m_pRecordset->GetCollect("姓名"));
m_grid.SetItemText(0,2,(char*)(_bstr_t)m_pRecordset->GetCollect("性别"));
m_pRecordset->MoveNext();
}
m_AdoConn.ExitConnect();//断开数据库连接
6:添加数据.
在对话框添加两个EditBox控件和一个Combox控件和一个按钮控件
如下图:
关联对象如下
[cpp] view plaincopy
CString m_id,m_name;CComboBox m_combo;
//在初始化中添加
m_combo.InsertString(0,"男");
m_combo.InsertString(1,"女");
m_combo.SetCurSel(0);
//按钮响应事件:
UpdateData(true);
if(m_id.IsEmpty())
{
MessageBox("编号不能为空");
return;
}
if(m_name.IsEmpty())
{
MessageBox("姓名不能为空");
return;
}
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
_bstr_t sql;
sql = "select*from employees";
_RecordsetPtr m_pRecordset;
m_pRecordset=m_AdoConn.GetRecordSet(sql);
CString sex;
m_combo.GetLBText(m_combo.GetCurSel(),sex);
try
{
m_pRecordset->AddNew();//添加新行
m_pRecordset->PutCollect("编号",(_bstr_t)m_id);
m_pRecordset->PutCollect("姓名",(_bstr_t)m_name);
m_pRecordset->PutCollect("性别",(_bstr_t)sex);
m_AdoConn.ExitConnect();
}
catch(...)
{
MessageBox("操作失败");
return;
}
MessageBox("保存成功");
m_grid.DeleteAllItems();
AddToGrid();//这个是用来显示数据的,就是第八步初始化中的代码
7 修改记录集
在添加一个EditBox控件,关联对象CString m_old;用来保存,修改之前的编号;
添加修改按钮,并响应事件,代码如下:
[cpp] view plaincopy
UpdateData(true);
if(m_name.IsEmpty())
{
MessageBox("姓名不能为空");
return;
}
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
_bstr_t sql;
sql = "select*from employees";
_RecordsetPtr m_pRecordset;
m_pRecordset=m_AdoConn.GetRecordSet(sql);
CString sex;
m_combo.GetLBText(m_combo.GetCurSel(),sex);
try
{
m_pRecordset->Move((long)pos,vtMissing);
m_pRecordset->PutCollect("编号",(_bstr_t)m_id);
m_pRecordset->PutCollect("姓名",(_bstr_t)m_name);
m_pRecordset->PutCollect("性别",(_bstr_t)sex);
m_pRecordset->Update();
m_AdoConn.ExitConnect();
}
catch(...)
{
MessageBox("操作失败");
return;
}
MessageBox("操作成功");
m_grid.DeleteAllItems();
AddToGrid();
8:删除记录集
UpdateData(true);
ADOConn m_AdoConn;
m_AdoConn.OnInitADOConn();
_bstr_t sql;
sql = "select*from employees";
_RecordsetPtr m_pRecordset;
m_pRecordset=m_AdoConn.GetRecordSet(sql);
CString m_id;
try
{
m_pRecordset->Move(pos,vtMissing);
m_pRecordset->Delete(adAffectCurrent);
m_pRecordset->Update();
m_AdoConn.ExitConnect();
}
catch(...)
{
MessageBox("操作失败");
return;
}
MessageBox("删除成功.");
m_grid.DeleteAllItems();
AddToGrid();
以上总结了,SQL连接四种基本操作
相关文章推荐
- VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
- VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
- ADO数据库访问技术使用的基本步骤及方法:
- VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
- VC中使用ADO访问数据库技术程序实现方法
- VC中使用ADO访问数据库技术程序实现方法
- VC中使用ADO访问数据库技术程序实现方法
- MFC连接SQL(ADO数据库访问技术)——绝对简单
- VC++中使用MFC通过ADO连接数据库方法小结
- MFC连接到SQL(ADO数据库访问技术)——表的查询,添加,删除
- VC++6.0下使用ADO技术访问SQL 数据库
- 使用ADO技术访问SQL 数据库
- MFC连接到SQL(ADO数据库访问技术)——表的查询,添加,删除
- VC基于ADO技术访问数据库的方法
- ADO.NET访问数据库-SqlCommand的ExecuteReader方法一般配合sqldatareader使用
- VC++中使用MFC通过ADO连接数据库方法小结
- VC++中使用MFC通过ADO连接数据库方法小结(不包括异常的捕捉
- VC下使用ADO数据库访问技术时遇到的问题
- VC使用ADO技术访问数据库
- VC++下使用ADO操作数据库的智能指针_ConnectionPtr、_RecordsetPtr、_CommandPtr的方法