其步骤一般分为:
(1) 引入ADO动态库文件
在stdafx.h添加以下代码引入ADO动态库文件
#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace\
rename("EOF","adoEOF")rename("BOF","adoBOF")
#import语句会在工程可执行程序输出目录中产生两个文件,分别为*.tlh(类型库头文件)及*.tli(类型库实现文件),它们分别为每一个接口产生智能指针,并为各种接口方法、枚举类型,CLSID等进行声明,创建一系列包装方法。语句no_namespace说明ADO对象不使用命名空间,rename ("EOF", "adoEOF")说明将ADO中结束标志EOF改为adoEOF,以避免和其它库中命名相冲突。
#import语句引用类型库时,生成的包装类.tlh中声明的智能指针中的三个,它们分别是_ConnectionPtr、_RecordsetPtr和_CommandPtr。
(2) 初始化COM环境
::CoInitialize(NULL); //初始化COM环境
::CoUninitialize(); //释放COM环境
(3) 连接数据库操作数据表
在这里先说一下2个数据类型:
_variant_t和_bstr_t这两个类分别封装并管理VARIANT和BSTR这两种数据类型,VARIANT和BSTR这两种类型是COM中使用的数据类型。
后面可以看到使用情况。
接下来就要开始利用之前所说的3个指针了(记住 这三个所产生的对象是指针)
_ConnectionPtr m_pConnection; // 数据库
_RecordsetPtr m_pRecordset; // 命令
_CommandPtr m_pCommand; // 记录
1.连接数据库
void Adosql::OnInitADOConn()
{
::CoInitialize(NULL);
try
{
m_pConnection.CreateInstance("ADODB.Connection");
_bstr_t strConnect="Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=master;Data Source=."; //数据库名称叫master 无密码
m_pConnection->Open(strConnect,"","",adModeUnknown); //打开数据库 接下来就可以对数据库进行操作了
AfxMessageBox("连接成功");
}
catch(_com_error e)
{
AfxMessageBox("连接失败");
}
}
2.数据库操作:
// 创建记录集对象
m_pRecordset.CreateInstance(__uuidof(Recordset));
// 取得表中的记录
m_pRecordset->Open("SELECT * FROM Class",m_pConnection.GetInterfacePtr
(),adOpenStatic,adLockOptimistic,adCmdText);//执行SQL语句,得到记录集, connection必须已和数
_variant_t vUsername,vID,vname; //变量声明
while(!m_pRecordset->adoEOF)///这里为什么是adoEOF而不是EOF呢?还记得rename("EOF","adoEOF")?
{
vID = m_pRecordset->GetFields()->GetItem((long)0)->GetValue();///取得第1列的值,从0开始计数,
strid = (TCHAR*)(_bstr_t)vID; //转换为字符串
vname = m_pRecordset->GetFields()->GetItem( (long)0)->GetName();;//取得第一列属性名
vUsername = m_pRecordset->GetCollect("名称");///根据表头取得数据
m_pRecordset->MoveNext();///移到下一条记录
CString tempstr=(LPCSTR)_bstr_t(vUsername);
//_variant_t 转换为cstring cstring转换为_variant_t 可以强转
}
//m_pRecordset->GetFields()->Count;//获得一条记录的字段数
m_pRecordset->MoveFirst();///移到首条记录
m_pRecordset->Delete(adAffectCurrent);///删除当前记录
///添加三条新记录并赋值
for(int i=0;i<3;i++)
{
m_pRecordset->AddNew();///添加新记录
m_pRecordset->PutCollect("班级", "3班");
m_pRecordset->PutCollect("名称","豆豆");
}
m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst));///从第一条记录往下移动一条记录,即移动到第二条记录处
m_pRecordset->PutCollect(_variant_t("班级"),"5班");///修改其年龄
m_pRecordset->Update();///保存到库中
当然还有多种方式来访问数据库:
(1)利用Connection对象的Execute方法执行SQL命令
Execute方法的原型如下所示:
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT *RecordsAffected, long Options ) 其中CommandText是命令字串,通常是SQL命令。参数RecordsAffected是操作完成后所影响的行数, 参数Options表示CommandText中内容的类型,Options可以取如下值之一:
adCmdText:表明CommandText是文本命令
adCmdTable:表明CommandText是一个表名
adCmdProc:表明CommandText是一个存储过程
adCmdUnknown:未知
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 _variant_t RecordsAffected;
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,oldINTEGER,birthday DATETIME)",&RecordsAffected,adCmdText);
///往表格里面添加记录
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday)valueS (1, nullnullnullnullnullnullnullnullWashingtonnullnullnullnullnullnullnullnull,25,nullnullnullnullnullnullnullnull1970/1/1nullnullnullnullnullnullnullnull)",&RecordsAffected,adCmdText);
///将所有记录old字段的值加一
m_pConnection->Execute("UPDATE users SET old =old+1",&RecordsAffected,adCmdText);
///执行SQL统计命令得到包含记录条数的记录集
m_pRecordset =m_pConnection->Execute("SELECT COUNT(*) FROMusers",&RecordsAffected,adCmdText);
_variant_t vIndex = (long)0;
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
m_pRecordset->Close();///关闭记录集
(2)利用Command对象来执行SQL命令
_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
_variant_t vNULL;
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
m_pRecordset =m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
ADO调用SQL Server存储过程
try{
if(m_pConnection==NULL) return;
m_pConnection->CursorLocation=adUseClient;//设置连接使用的光标类型
m_pRecordset.CreateInstance("ADODB.Recordset");
_CommandPtr m_pCommand;//初始化命令对象
m_pCommand.CreateInstance("ADODB.Command");//创建命令实例
m_pCommand->ActiveConnection=m_pConnection;//设置命令对象的连接
m_pCOmmand->CommandType=adCmdStoredProc;//设置命令对象处理的类型,在此为处理存储过程
m_pCommand->CommandText=_bstr_t(_T("GetEmployeeByName"));//其中GetEmployeeByName是存储过程的名称
m_pCommand->Parameters->Refresh();//刷新命令参数值
m_pCommand->Parameters->Item[_variant_t(_bstr_t("@EmployeeID"))]->Value=_variant_t(short(atoi(m_ID)));
//设置字段EmployeeID的值为@EmployeeID
m_pRecordset=m_pCommand->Execute(NULL,NULL,adCmdStoredProc)://执行存储过程
int iResult=-1;
_variant_t vResult;
vResult=m_pCommand->Parameters->GetItem(short(2))->Value;//获取返回值
iResult=vResult.intVal;//将返回值转换为int类型
CString log;
log.Format("调用存储过程,共查询到%d条记录",iResult);
if(m_pRecordset->RecordCount<=0){
m_pRecordset->Close();
m_pRecordset=NULL
m_pCommand.Detach();//释放命令对象
return;
}
else{}
}catch(_com_error e){
}