1 引入ADO库文件
使用ADO前必须在工程的stdafx.h文件最后用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下:
#import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace rename("EOF","adoEOF")
ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。类型库描述了自治接口,以及C++使用的COM vtable接口。当使用#import指令时,在运行时Visual C++需要从ADO DLL中读取这个类型库,并以此创建一组C++头文件。这些头文件具有.tli 和.tlh扩展名,读者可以在项目的目录下找到这两个文件。在C++程序代码中调用的ADO类要在这些文件中定义。代码将ADO中的EOF(文件结束)更名为adoEOF,以避免与定义了自己的EOF的其他库冲突。
2 生成应用框架并初始化OLE|COM环境
创建一个标准的MFC AppWizard(exe)程序,然后在框架OnInitDialog()函数中初始化OLE/COM环境,如下:
BOOL CADOTestDlg::OnInitDialog()
{
CoInitialize(NULL);//初始化COM环境
};
在程序结束是,调用OnDestroy()函数,结束OLE/COM环境,释放其占有的资源。
CoUninitialize();//释放占有的资源
3 定义智能指针
public:
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
_ConnectionPt用于连接数据,也可以方便的对数据库进行操作。
_RecordsetPtr作为数据库操作返回集,查询完的数据存在里面。
在构造函数中,初始化他们为null,程序最后也要初始化他们,进行资源释放。
4 连接数据库
void CADOTestDlg::OnButtonconnect()
{
// TODO: Add your control notification handler code here
m_pConnection.CreateInstance(_uuidof(Connection));//初始化m_pConnection,生成一个实例
//try{}catch(){}是数据库操作中经常用的组合,可以捕捉错误信息有利于调试
try
{
//m_pConnection->Open进行连接数据库。记住格式
m_pConnection->Open("Provider=OraOLEDB.Oracle;Password=tiger;User ID=scott;Data Source=myoracle","","",0);
AfxMessageBox("连接成功");
}
catch (_com_error e)
{
AfxMessageBox(e.ErrorMessage());
}
}
Open函数的第一个参数包含了provider,password,user ID,data source四项数据库信息。
5 查询数据库
void CADOTestDlg::OnButtonselect()
{
m_pRecordset.CreateInstance(_uuidof(Recordset));//初始化m_pRecordset,生成一个实例
_variant_t recordvariant;
try
{
CString sqlstr;
sqlstr.Format("select *from scott.student");//一个SQL语句
//利用Connection执行这个SQL语句,并把结果返回m_pRecordset记录集
m_pRecordset=m_pConnection->Execute((_bstr_t)sqlstr,&recordvariant,adCmdText);
while (!m_pRecordset->adoEOF)
{
//读取各个字段的值
_bstr_t value_name=m_pRecordset->Fields->GetItem("NAME")->Value;
_bstr_t value_id=m_pRecordset->Fields->GetItem("ID")->Value;
_bstr_t value_professiongal=m_pRecordset->Fields->GetItem("PROFRESSIONAL")->Value;
_bstr_t value_age=m_pRecordset->Fields->GetItem("AGE")->Value;
_bstr_t value_th_id=m_pRecordset->Fields->GetItem("TH_ID")->Value;
CString name_str,id_str,professionalfu_str,age_str,th_id_str;
//转化为Cstring类型
name_str.Format("%s",(const char*)value_name);
id_str.Format("%s",(const char*)value_id);
professionalfu_str.Format("%s",(const char*)value_professiongal);
age_str.Format("%s",(const char*)value_age);
th_id_str.Format("%s",(const char*)value_th_id);
//向list表插入, 博主补充,m_list是listview控件
m_list.InsertItem(0,LPSTR_TEXTCALLBACK);
m_list.SetItemText(0,0,id_str);
m_list.SetItemText(0,1,name_str);
m_list.SetItemText(0,2,professionalfu_str);
m_list.SetItemText(0,3,age_str);
m_list.SetItemText(0,4,th_id_str);
//指向下一条记录
m_pRecordset->MoveNext();
}
}
catch(_com_error e)
{
e.ErrorMessage();
}
}
Connection 执行SQL语句Execute的原型如下:
Execute ( _bstr_t CommandText, VARIANT *RecordsAffected, long Options )
CommandText是SQL语句,但是一定要把包含SQL语句的字符串转化为_bstr_t类型;RecordsAffected是_variant_t类型,是操作完成后影响的行数;Options指示CommandText中内容类型,具体取值如下:
adCmdText:表明CommandText是文本命令,一般就是这个参数
adCmdTable:表明CommandText是一个表名
adCmdProc:表明CommandText是一个存储过程
adCmdUnknown:未知
除了可以用connection执行SQL语句外,还可以用Command和recordset执行。
6 插入数据库
void CADOTestDlg::OnButtoninsert()
{
//控件向变量传递值
UpdateData(TRUE);
_variant_t recordvariant;
CString SQLstr;
SQLstr.Format("INSERT INTO SCOTT.STUDENT(ID,NAME,PROFRESSIONAL,AGE,TH_ID) VALUES(%d,'%s','%s',%d,%d)",id_int,m_namestr,m_prostr,age_int,th_id_int);
try
{
m_pConnection->Execute((_bstr_t)SQLstr,&recordvariant,adCmdText);
AfxMessageBox("插入成功");
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
}
}
SQL语句中的知识点:
在VC中,如果SQL语句中有变量,其形式是这样的。如果是字符变量,则用’%s’关联,如果是整型变量,则用%d关联。
7 更新和删除
基本上和上面的一样。
void CADOTestDlg::OnButtonupdata()
{
_variant_t recordvariant;
try
{
m_pConnection->Execute("update scott.student set NAME='sssss' where ID=10000001",
&recordvariant,adCmdText);
AfxMessageBox("更新成功");
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
}
}
//删除
void CADOTestDlg::OnButtondelete()
{
_variant_t recordvariant;
try
{
m_pConnection->Execute("delete from scott.student where ID=10000004",
&recordvariant,adCmdText);
AfxMessageBox("删除成功");
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
}
}