MSDN中提供MFC的连接数据库的方法大约有三种方法
一是CDatabase类(ODBC),一是DAO,另一是OLE DB,MSDN上推荐的方法是ODBC或者OLE DB方式。
OLE DB是一组”组件对象模型”(COM) 接口,是新的数据库低层接口,它封装了ODBC的功能,并以统一的方式访问存储在不同信息源中的数据。OLE DB是Microsoft UDA(Universal Data Access)策略的技术基础。OLE DB 为任何数据源提供了高性能的访问,这些数据源包括关系和非关系数据库、电子邮件和文件系统、文本和图形、自定义业务对象等等。也就是说,OLE DB 并不局限于 ISAM、Jet 甚至关系数据源,它能够处理任何类型的数据,而不考虑它们的格式和存储方法。在实际应用中,这种多样性意味着可以访问驻留在 Excel 电子数据表、文本文件、电子邮件/目录服务甚至邮件服务器,诸如 Microsoft Exchange 中的数据。但是,OLE DB 应用程序编程接口的目的是为各种应用程序提供最佳的功能,它并不符合简单化的要求。您需要的API 应该是一座连接应用程序和OLE DB 的桥梁,这就是 ActiveX Data Objects (ADO)。
使用ADO前必须在工程的stdafx.h头文件里用直接引入符号#import引入ADO库文件,以使编译器能正确编译。
ADO库是一组COM动态库,这意味应用程序在调用ADO前,必须初始化OLE/COM库环境。在MFC应用程序里,一个比较好的方法是在应用程序主类的InitInstance成员函数里初始化OLE/COM库环境。
然后ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口
下面是编程步骤:
1、在StdAfx.h加入:
#import "c:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
|
2、初始化OLE/COM库,这个在应用程序类的InitInstance函数里面添加即可
if (!AfxOleInit())
{
AfxMessageBox("OLE init Error");
return FALSE;
}
|
我在网上看到还需要添加如下代码初始化com库
CoInitialize(NULL);// CoInitializeEx(NULL);
|
但是我并没有添加,却连接数据库成功,可能是和上面的初始化有相同的功能,或者AfxOleInit初始化时候调用了CoInitializeEx,不过如果在多线程下貌似需要在每个线程调用CoInitializeEx,等我后面用到了,在更新文章
3、我只介绍我用到的接口,上面是初始化系统环境,下面声明一个接口
4、打开链接
const _bstr_t strSRC= "Driver={SQL Server};PROVIDER=SQLOLEDB;Data Source=SVCTAG-D76XZ2X;Database=bridge;Uid=test;Pwd=test;";
if (FAILED(pConn.CreateInstance("ADODB.Connection")))
{
AfxMessageBox("Create Instance failed!");
exit(0);
}
try{
pConn->Open(strSRC,"","",-1);
}
catch (_com_error &e)
{
AfxMessageBox(e.Description());
exit(0);
}
|
5、到此与数据库的连接顺利建立,下面就是执行sql语句,获取结果了
int CBridgeSql::execSql(CString sql)
{
COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
try
{
pConn->Execute(_bstr_t(sql),&vtOptional,adCmdText);
}catch(_com_error &e){
TRACE(sql);
AfxMessageBox(e.Description());
return -1;
}
return 0;
}
int CBridgeSql::execSql(CString sql,_RecordsetPtr &pRst)
{
COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
try
{
pRst=pConn->Execute(_bstr_t(sql),&vtOptional,adCmdText);
}catch(_com_error &e){
TRACE(sql);
AfxMessageBox(e.Description());
return -1;
}
return 0;
}
|
调用代码如下
_RecordsetPtr pRst(__uuidof(Recordset));
sql_cmd.Format("select * from bridge"); execSql(sql_cmd,pRst);
while(!pRst->adoEOF)
{
pRst->GetCollect("bridge_id").intVal;
CString temp;
temp.Format((_bstr_t)pRst->GetCollect("name"));
}
|
其余两个接口有空再整理一下,上面问题,我会验证,待续
阅读(12084) | 评论(0) | 转发(0) |