在VC中使用ADO

来源:互联网 发布:高压电棍专卖淘宝 编辑:程序博客网 时间:2024/04/30 03:53

一、ADO概述 
ADO是Microsoft为最新和最强大的数据访问范例 OLE DB 而设计的,是一个便于使用的应用程序层接口。ADO 使您能够编写应用程序以通过 OLE. DB 提供者访问和操作数据库服务器中的数据。ADO 最主要的优点是易于使用、速度快、内存支出少和磁盘遗迹小。ADO 在关键的应用方案中使用最少的网络流量,并且在前端和数据源之间使用最少的层数,所有这些都是为了提供轻量、高性能的接口。之所以称为 ADO,是用了一个比较熟悉的暗喻,OLE 自动化接口。

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)。

二、在VC中使用ADO

1、引入ADO库文件

使用ADO前必须在工程的stdafx.h头文件里用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下所示:

#import "c:\program files\common files\system\ado\msado15.dll"no_namespaces rename("EOF" adoEOF")

这行语句声明在工程中使用ADO,但不使用ADO的名字空间,并且为了避免常数冲突,将常数EOF改名为adoEOF。现在不需添加另外的头文件,就可以使用ADO接口了。

2、初始化OLE/COM库环境

ADO库是一组COM动态库,这意味应用程序在调用ADO前,必须初始化OLE/COM库环境。在MFC应用程序里,一个比较好的方法是在应用程序主类的InitInstance成员函数里初始化OLE/COM库环境。

BOOL CAdoTestApp::InitInstance() { if(!AfxOleInit())//这就是初始化COM库 {   AfxMessageBox(“OLE初始化出错!”);   return FALSE; }……}
你也可以使用“::CoInitialize(NULL);”来初始化OLE/COM库环境,用“::CoUninitialize();”来取消初始化。

3、ADO接口简介

ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。

_ConnectionPtr接口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。使用_ConnectionPtr接口返回一个记录集不是一个好的使用方法。对于要返回记录的操作通常用_RecordserPtr来实现。而用_ConnectionPtr操作时要想得到记录条数得遍历所有记录,而用_RecordserPtr时不需要。

_CommandPtr接口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,你可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据访问操作,后者是比较好的选择。但如果你要频繁访问数据库,并要返回很多记录集,那么,你应该使用全局_ConnectionPtr接口创建一个数据连接,然后使用_CommandPtr接口执行存储过程和SQL语句。

_RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定,游标控制等。同_CommandPtr接口一样,它不一定要使用一个已经创建的数据连接,可以用一个连接串代替连接指针赋给_RecordsetPtr的connection成员变量,让它自己创建数据连接。如果你要使用多个记录集,最好的方法是同Command对象一样使用已经创建了数据连接的全局_ConnectionPtr接口 
,然后使用_RecordsetPtr执行存储过程和SQL语句。

4、使用_ConnectionPtr接口 

_ConnectionPtr主要是一个连接接口,取得与数据库的连接。它的连接字符串可以是自己直接写,也可以指向一个ODBC DSN(ODBC数据源名称)。

// 打开数据库连接

bool CADODB::OpenDB()     {HRESULT hr =  m_pConnection.CreateInstance("ADODB.Connection");// 创建Connection对象if (hr != S_OK){AfxMessageBox("创建链接对象失败");return false;}hr = m_pConnection->Open(m_strConn,(_bstr_t)"",(_bstr_t)"",adModeUnknown);if (hr != S_OK){AfxMessageBox("链接数据库失败");return false;}return true;}
// 关闭数据库连接
bool CADODB::CloseDB(){if(m_pConnection ){m_pConnection->Close();     m_pConnection = NULL; }return true;}

// 创建表格

 _variant_t RecordsAffected;  CString sql;  // 创建一个表格  sql.Format("CREATE TABLE files(FileID INTEGER,FilePath TEXT,FileData VARBINARY(MAX))");  m_pConnection->Execute(sql.AllocSysString(),&RecordsAffected,adCmdText);

// 创建记录集

_RecordsetPtr pRecordset;    HRESULT hr = pRecordset.CreateInstance("ADODB.Recordset");   if (hr != S_OK){  AfxMessageBox("创建记录集对象失败");  }

/× --- 插入二进制文件数据 ---×/

// 取得二进制数据CFile file;if (!file.Open("D:\\MSSQL\\DATA\\pdf\\2.pdf", CFile::modeRead)){AfxMessageBox("Cannot open file.");AfxThrowUserException();}ULONGLONG ullLength = (ULONGLONG)file.GetLength();int dwSize = (DWORD)ullLength;BYTE * binData = new BYTE[dwSize];file.Read(binData, dwSize);file.Close();//SAFEARRAY *psa;               //安全数组指针SAFEARRAYBOUND rgsabound[1];  //安全数组范围描述VARIANT varBLOB;              //填充变量if(binData!=NULL){rgsabound[0].lLbound=0;rgsabound[0].cElements = dwSize;psa=::SafeArrayCreate(VT_UI1, 1, rgsabound);        //创建SAFEARRAY对象for(long i=0;i<(long)dwSize;i++){//将pBuf指向的二进制数据保存到SAFEARRAY对象psa中::SafeArrayPutElement(psa,&i,binData++);}varBLOB.vt=VT_ARRAY|VT_UI1;                   //将varBLOB的类型设置为BYTE类型的数组varBLOB.parray=psa;                           //为varBLOB变量赋值}
//  插入数据
    sql.Format(_T("select FileData from files"));    hr = pRecordset->Open(sql.AllocSysString(),(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText);    pRecordset->MoveFirst();    pRecordset->GetFields()->GetItem((_variant_t)(long)(0))->AppendChunk(varBLOB);    pRecordset->Update();


//  读取二进制文件数据

        sql.Format(_T("select FileData from files"));hr = pRecordset->Open(sql.AllocSysString(),(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText);pRecordset->MoveFirst();size = pRecordset->GetFields()->GetItem((_variant_t)(long)(0))->ActualSize;if(size>0){varBLOB = pRecordset->GetFields()->GetItem((_variant_t)(long)(0))->GetChunk(size);if(varBLOB.vt==(VT_ARRAY|VT_UI1)){//开启数据获取::SafeArrayAccessData(varBLOB.parray,(void **)&re);//关闭数据获取::SafeArrayUnaccessData (varBLOB.parray);}}


以上代码有些只是关键代码,并未包含所有需要注意到地方,如,内存的释放等。

本文因工作需要而记录,并非全面描述ADO的使用。

以上代码在vs2008sp1 + windows 7 sp1环境下测试通过。


参考文档:

http://www.cnblogs.com/loving-my-gf/archive/2011/12/09/2281576.html

原创粉丝点击