您的位置:首页 > 编程语言 > C语言/C++

VC++使用ADO方法读写Microsoft Access本地数据库文件(不用ODBC)

2013-08-04 00:44 405 查看
本文出处: http://blog.csdn.net/word_world/article/details/9738407
特点:

像对待文件一样创建/读/写Access数据库,无须创建数据源.

说明:

作者为此写了一个类FAdoDbHandler,其声明和实现分别放在FAdoDbHandler.h和FAdoDbHandler.cpp文件中,测试代码置于main.cpp中.

以下代码在VC++6.0下测试通过(控制台应用程序 项目设置中使用MFC)

Access 版本为 2003

/*┏━━━━━━━━━━━━━━━━━━━┓
┃  文件名: FAdoDbHandler.h            ┃
┣━━━━━━━━━━━━━━━━━━━┫
┃  描  述: FAdoDbHandler 类的声明     ┃
┣━━━━━━━━━━━━━━━━━━━┫
┃  作  者:张石磊 fstone.zh@foxmail.com┃
┣━━━━━━━━━━━━━━━━━━━┫
┃  更新日期:2013-08-01              ┃
┗━━━━━━━━━━━━━━━━━━━┛*/
#ifndef __FADODBHANDLER_HEADER__
#define __FADODBHANDLER_HEADER__

#include <iostream>
#include <vector>

#import "C:/Program Files/Common Files/System/ado/msadox.dll"							//no_namespace //ADOX
#import "C:/Program Files/Common Files/System/ado/msado15.dll"  rename("EOF","adoEOF")	// no_namespace // 不使用命名空间 ADODB
//#pragma warning (disable:4146)
//#pragma warning (default:4146)
class FAdoDbHandler
{

protected:// 类成员
static const std::string ACCESS_PROVIDER;	// Access数据库驱动程序
static bool _bInitialized;					// COM环境已初始化标志
static std::vector<FAdoDbHandler*> * _dbHandlers;
protected:// 对象成员
ADOX::_CatalogPtr _pCatalog;				// 数据库智能指针
ADODB::_ConnectionPtr _pConnection;			// 连接智能指针
ADOX::_TablePtr _pTable;					// 表指针
//ADODB::_RecordsetPtr _pRecordset;			// select结果记录集

std::string _dbFullPathName;				// 完整路径数据库名
std::string _dbNameWithProvider;			// 带驱动程序名的数据库名

public:// 静态成员函数
// 创建一个FAdoDbHandler对象
static FAdoDbHandler * CreateHandler();
// 清理FAdoDbHandler对象
static void CleanUp();

public:// 非静态成员函数
bool CreateDatabase(char* dbFullPathName);	// 创建数据库
bool ConnectDatabase(char* dbFullPathName);	// 连接数据库
bool Connect();								// 连接当前数据库
void Disconnect();							// 断开当前数据库的连接
bool ExistTable(char* tbName);				// 判断表是否在当前数据库中存在
int  CreateTable(char* tbName,char* szSQL);	// 在当前数据库中创建表
int  ExecuteNonQuery(char* szSQL);			// 执行insert update delete语句
ADODB::_RecordsetPtr ExecuteQuery(char* szSQL);// 执行 select 语句

protected:// 隐藏构造函数
FAdoDbHandler();
virtual ~FAdoDbHandler();

protected:// 辅助函数
// 生成带驱动程序的数据库名
static std::string FormatDbNameWithProvider(char* dbFullPathName);

};

#endif


/*┏━━━━━━━━━━━━━━━━━━━┓
┃  文件名: FAdoDbHandler.cpp          ┃
┣━━━━━━━━━━━━━━━━━━━┫
┃  描  述: FAdoDbHandler 类的实现     ┃
┣━━━━━━━━━━━━━━━━━━━┫
┃  作  者:张石磊 fstone.zh@foxmail.com┃
┣━━━━━━━━━━━━━━━━━━━┫
┃  更新日期:2013-08-01              ┃
┗━━━━━━━━━━━━━━━━━━━┛*/
#include "FAdoDbHandler.h"

/*┏━━━━━━━━━━━━━━━━━━━┓
┃    静态成员                          ┃
┗━━━━━━━━━━━━━━━━━━━┛*/

// Acess数据库驱动程序
const std::string FAdoDbHandler::ACCESS_PROVIDER = "Microsoft.Jet.OLEDB.4.0";
// COM环境是否已经初始化
bool FAdoDbHandler::_bInitialized = false;
// FAdoDbHandler池
std::vector<FAdoDbHandler*> * FAdoDbHandler::_dbHandlers = new std::vector<FAdoDbHandler*>();

/************************************************************
* 获取一个独立的FAdoDbHandler对象指针
************************************************************/
FAdoDbHandler* FAdoDbHandler::CreateHandler()
{
if(!_bInitialized)
{
// 初始化 COM 环境
HRESULT hRe =S_OK;
hRe = ::CoInitialize(NULL);
if(!SUCCEEDED(hRe))
{
std::cout<<"初始化COM环境失败"<<std::endl;
return 0;
}
_bInitialized = true;
std::cout<<"初始化COM环境成功"<<std::endl;
}

FAdoDbHandler* instance = new FAdoDbHandler();
// 将新对象加入图中
_dbHandlers->push_back(instance);

return instance;
}

/************************************************************
* 清理FAdoDbHandler对象
************************************************************/
void FAdoDbHandler::CleanUp()
{
if(NULL != _dbHandlers)
{
std::vector<FAdoDbHandler*>::iterator itr = _dbHandlers->begin();
// 销毁全部FAdoDbHandler对象
while(itr!=_dbHandlers->end())
{
delete *itr;
*itr = 0;
itr++;
}
_dbHandlers->clear();
}
}

/*┏━━━━━━━━━━━━━━━━━━━┓
┃    隐藏构造/析构函数                 ┃
┗━━━━━━━━━━━━━━━━━━━┛*/

/************************************************************
* 构造函数
************************************************************/
FAdoDbHandler::FAdoDbHandler()
{
//_pRecordset = NULL;
_pTable = NULL;
_pConnection = NULL;
_pCatalog = NULL;

_dbFullPathName = "";
_dbNameWithProvider = "";

}

/************************************************************
* 析构函数
************************************************************/
FAdoDbHandler::~FAdoDbHandler()
{
std::cout<<"--------析构函数---------"<<std::endl;
// 释放智能指针
//_pRecordset = NULL;
_pTable = NULL;
_pConnection = NULL;
_pCatalog = NULL;

//断开连接
Disconnect();

}

/*┏━━━━━━━━━━━━━━━━━━━┓
┃    非静态成员函数                    ┃
┗━━━━━━━━━━━━━━━━━━━┛*/
/************************************************************
* 创建数据库 (create database .. )
* dbFullPathName	: 包含路径名的*.mdb文件名
* 返回				: true,创建成功; fasle,失败
************************************************************/
bool FAdoDbHandler::CreateDatabase(char* dbFullPathName)
{
// 保存数据库全名 和 带驱动程序名的数据库名
_dbFullPathName = dbFullPathName;
_dbNameWithProvider = FormatDbNameWithProvider(dbFullPathName);
// 创建数据库
try{
_pCatalog.CreateInstance(__uuidof (ADOX::Catalog) );	// 获取智能指针实例
_pCatalog->Create( _bstr_t(_dbNameWithProvider.c_str()) );
_pCatalog = NULL;										// 释放智能指针
}
catch(_com_error & e)
{
std::cout<<"创建数据库失败"<<e.ErrorMessage()<<std::endl;
return false;
}
std::cout<<"创建数据库成功"<<std::endl;
return true;
}

/************************************************************
* 连接数据库 (use .. )
* dbFullPathName	: 包含路径名的*.mdb文件名
* 返回				: true,连接到数据库; fasle,连接失败
************************************************************/
bool FAdoDbHandler::ConnectDatabase(char* dbFullPathName)
{
// 保存数据库全名 和 带驱动程序名的数据库名
_dbFullPathName = dbFullPathName;
_dbNameWithProvider = FormatDbNameWithProvider(dbFullPathName);
// 连接数据库
Connect();
return true;
}

/************************************************************
* 连接当前数据库 (use .. )
* 返回				: true,连接到数据库; fasle,连接失败
************************************************************/
bool FAdoDbHandler::Connect()
{
try{
_pConnection = NULL;
// 实例智能指针
_pConnection.CreateInstance(__uuidof(ADODB::Connection));
// 打开连接
_pConnection->Open(_bstr_t(_dbNameWithProvider.c_str()), "", "", ADODB::adModeUnknown);
}
catch( _com_error & err)
{
std::cout<<"连接失败"<<err.ErrorMessage()<<std::endl;
return false;
}
std::cout<<"成功连接到数据库"<<std::endl;
return true;
}

/************************************************************
* 断开当前数据库的连接
************************************************************/
void FAdoDbHandler::Disconnect()
{
try
{
if(NULL!=_pConnection && _pConnection->State)
{
_pConnection->Close();	// 关闭连接
_pConnection = NULL;	// 释放智能指针
}
else
{
std::cout<<"连接已经断开"<<std::endl;
return;
}
}
catch(_com_error & err)
{
std::cout<<"断开连接异常"<<err.ErrorMessage()<<std::endl;
}
std::cout<<"成功断开连接"<<std::endl;
}

/************************************************************
* 判断表是否在当前数据库中存在
************************************************************/
bool FAdoDbHandler::ExistTable(char* tbName)
{
if(NULL == _pConnection || !_pConnection->State)
return false;
_pTable = NULL;
try{
_pCatalog.CreateInstance(__uuidof(ADOX::Catalog));
// 激活db连接,相当于SQL语句use [db_name];
_pCatalog->PutActiveConnection(_bstr_t(_dbNameWithProvider.c_str()));
// 数据库中表总数
int nTableCnt = _pCatalog->Tables->Count;
// 逐表对照表名
for(int i=0; i<nTableCnt; i++)
{
_pTable = (ADOX::_TablePtr)_pCatalog->Tables->GetItem(long(i));
std::string existTableName = _pTable->Name;
if(!existTableName.compare(tbName))
return true;
}
_pCatalog = NULL;
}
catch(_com_error & err)
{
std::cout<<"ExistTable"<<err.ErrorMessage()<<std::endl;
return false;
}
return false;
}

/************************************************************
* 在当前数据库中创建表 (create table)
* tbName : 要创建的表名
* szSQL  : 创建表的SQL语句
* 返回	  : -1,创建出错; 0,表已经存在; >0,创建成功
************************************************************/
int FAdoDbHandler::CreateTable(char* tbName,char* szSQL)
{
// 检查表是否存在
if(!ExistTable(tbName))
{
if(ExecuteNonQuery(szSQL) >= 0)
return 1;	// 成功
else
return -1;	// 创建出错
}
return 0;			// 表已存在
}

/************************************************************
* 执行不返回记录集的命令 (insert update delete)
* szSQL: 要执行的SQL语句
* 返回: >=0 执行完此SQL语句受影响的记录行数
*		 < 0 出错
************************************************************/
int  FAdoDbHandler::ExecuteNonQuery(char* szSQL)
{
_variant_t nRecordsAffected;	// 受影响的记录数
try{
_pConnection->Execute(_bstr_t(szSQL), &nRecordsAffected, ADODB::adModeUnknown);
}
catch( _com_error & err)
{
std::cout<<"ExecuteNonQuery出错"<<err.ErrorMessage()<<std::endl;
return -1;
}
std::cout<<"ExecuteNonQuery成功"<<std::endl;
return nRecordsAffected.intVal;
}

/************************************************************
* 执行返回记录集的命令 (select)
* szSQL: 要执行的SQL语句
* 返回: 结果记录集智能指针
************************************************************/
ADODB::_RecordsetPtr  FAdoDbHandler::ExecuteQuery(char* szSQL)
{
_variant_t nRecordsAffected;
ADODB::_RecordsetPtr rcdset = NULL;
try{
rcdset.CreateInstance("ADODB.Record");				// 初始化记录集智能指针实例
rcdset = _pConnection->Execute(	_bstr_t(szSQL),
&nRecordsAffected,
ADODB::adCmdText);	// 执行select语句
}
catch( _com_error & err)
{
std::cout<<"ExecuteQuery失败"<<err.ErrorMessage()<<std::endl;
return NULL;
}
std::cout<<"ExecuteQuery成功"<<std::endl;

// 返回结果记录集
return rcdset;
}

/*┏━━━━━━━━━━━━━━━━━━━┓
┃    辅助函数                          ┃
┗━━━━━━━━━━━━━━━━━━━┛*/

/************************************************************
* 生成带驱动程序的数据库名
************************************************************/
std::string FAdoDbHandler::FormatDbNameWithProvider(char* dbFullPathName)
{
std::string str = "Provider=";
str.append(ACCESS_PROVIDER);
str.append(";Data Source=");
str.append(dbFullPathName);
return str;
}


/*┏━━━━━━━━━━━━━━━━━━━┓
┃  文件名: main.cpp                   ┃
┣━━━━━━━━━━━━━━━━━━━┫
┃  描  述: 程序入口                   ┃
┣━━━━━━━━━━━━━━━━━━━┫
┃  作  者:张石磊 fstone.zh@foxmail.com┃
┣━━━━━━━━━━━━━━━━━━━┫
┃  更新日期:2013-08-01              ┃
┗━━━━━━━━━━━━━━━━━━━┛*/
#include "fstone/db/ado/FAdoDbHandler.h"

int main()
{
FAdoDbHandler * db = FAdoDbHandler::CreateHandler();

db->CreateDatabase("database\\db1.mdb");
db->Connect();

//db->ConnectDatabase("database\\db1.mdb");

char * szSql = "create table test3(id int,namestr char(8));";
int n = db->CreateTable("test3",szSql);
std::cout<<"建表返回值: "<<n<<std::endl;
n = db->ExecuteNonQuery("insert into test3(id,namestr)values(15,'Fiftn');");
//n = db->ExecuteNonQuery("delete from test3");
std::cout<<"插入返回值: "<<n<<std::endl;

ADODB::_RecordsetPtr result;
result = db->ExecuteQuery("select * from test3");

_variant_t tmp;
try{
if(NULL != result)
{
while( !result->adoEOF )
{
tmp = result->GetCollect("id");
int id = tmp.intVal;
std::cout<<"id = "<<id<<std::endl;
tmp = result->GetCollect("namestr");
std::string name = (_bstr_t)tmp;
std::cout<<"name = "<<name.c_str()<<std::endl;
result->MoveNext();
}
result->Close();
result = NULL;
}
}
catch( _com_error & err)
{
}

db->Disconnect();

FAdoDbHandler::CleanUp();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: