1. 程式人生 > >分享關於VC 使用ADO資料庫使用的方法封裝類

分享關於VC 使用ADO資料庫使用的方法封裝類

ADO是目前還較新的訪問資料庫的一種方法,該型別庫提供了 使用各個型別版本資料庫的公共介面,從檔案訪問資料,網路訪問資料,等等操作資料集的一些方法,

接下來分享下關於操作access資料庫的方法封裝類 以此為例,其他資料庫訪問大同小異:

#import"C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace rename("EOF","adoEOF") rename("BOF","adoBOF")
#import"C:/Program Files/Common Files/System/ado/Msadox.dll"  rename_namespace("ADOCG") rename("EOF", "adoXEOF") rename("DataTypeEnum","adoXDataTypeEnum")  
using namespace ADOCG;
#define TESTHR(x) if FAILED(x) _com_issue_error(x);
#pragma warning (disable: 4146)
#pragma warning (default: 4146)
#include<stdio.h>
#include<iostream>
#include<fstream>
#include <string>
#include <vector>
using namespace std;


struct FIELDSINFO
{
FIELDSINFO(){
IsSetZero=true;//是否清零
IsSetPrimaryKey=false;//是否設為主鍵
}
string strFieldsName;//欄位名
bool IsSetZero;//是否清零
bool IsSetPrimaryKey;//是否設為主鍵
};


class CKpAdoDatabase
{
public:
CKpAdoDatabase(void);
virtual ~CKpAdoDatabase(void);
public:
BOOL OpenMdb(LPSTR szMdbPath);//建立Connection介面 連結資料庫
void OpenMdbTable(LPCSTR pszTableNmae);//開啟資料庫表 
void CloseTable();//關閉記錄集表
void Close(); //關閉資料庫連線
public:
void AddNew(LONG lnIndex=0,LPSTR Value="0");//新增記錄
void SetValue(LONG lnIndex,LPCSTR Value);//修改記錄
void Delete(_In_ int iIndex,_In_ int nCount = 1);
void FindData(LPCSTR pszTableNmae,LPCSTR pszWhereKey,LPCSTR pszValue,vector<LPCSTR>& vecName);//根據條件查詢(SQL) 獲取記錄集
public:
ULONG GetrecordCount();//獲取記錄集的數量
ULONG GetFieldCount();//獲取欄位的數量
BOOL GetFieldInfo(long nIndex,string& strName);//獲取欄位的資訊
BOOL GetFieldCollect(long nIndex,string& strName);//獲取記錄
void MoveNext();//遊標向後
void MovePrevious();//遊標向前
void MoveFirst();//頭
void MoveLast();//尾
BOOL IsBOF();     //判斷遊標指標是否在記錄頭部
BOOL IsEOF();     //判斷遊標指標是否在記錄尾部
void Update();//更新資料庫
public:
BOOL IsHaveFile( LPSTR pszPath );
BOOL CreateMdb(string strMdbName);//建立ACCESS資料庫 
BOOL CreateTable( string strMdbName,string strTabName,vector<FIELDSINFO*>& vecFields);//建立資料庫表
BOOL IsTalbeExit(string strTable);//判斷一個表在資料庫中是否存在
public:
_ConnectionPtr m_pConnection;//定義ADO資料庫連線指標
_RecordsetPtr m_pRecordset;//定義記錄集指標
};

#include "KpAdoDatabase.h"
#include "shlwapi.h"
#include "KpString.h"


CKpAdoDatabase::CKpAdoDatabase(void)
{
::CoInitialize(NULL);//初始化資料庫COM庫
}


CKpAdoDatabase::~CKpAdoDatabase(void)
{
::CoUninitialize();
}
/************************************************
  函式名稱:OpenMdb
  函式功能:連線資料庫 (這裡主要是ACCESS資料庫……)
  輸入引數:
szMdbPath  資料庫路徑
  輸出引數:
  BOOL
*************************************************/
BOOL CKpAdoDatabase:: OpenMdb(LPSTR szMdbPath)
{
try{
HRESULT nRet=m_pConnection.CreateInstance(__uuidof(Connection));//建立Connection介面 例項化 m_pConnection指標
if(FAILED(nRet))return FALSE;
//構造ACCESS資料庫連線字串
char szConn[MAX_PATH]={0};
sprintf(szConn,"Provider=Microsoft.Jet.OLEDB.4.0;"//連線ACCESS資料庫
"Data Source=%s;User ID=;Password=;",szMdbPath);
//構造Oracle連結字串方式 如下
//sprintf(szConn,"Provider=OraOLEDB.Oracle.1;Password=tiger;User ID=scott;Data Source=%s;Persist Security Info=true","orcl");
//連線資料
m_pConnection->Open(_bstr_t(szConn),"","",adConnectUnspecified);
if(FAILED(nRet)){
return FALSE;
}
}catch(...){
return FALSE;
}
return TRUE;
}
/************************************************
  函式名稱:OpenMdbTable
  函式功能:開啟資料庫表
  輸入引數:
pszTableNmae  資料庫表名稱
  輸出引數:
  void
*************************************************/
void CKpAdoDatabase:: OpenMdbTable(LPCSTR pszTableNmae)
{
    m_pRecordset.CreateInstance(__uuidof(Recordset));  //例項化 m_pRecordset指標
    string strSql="select * from ";                    //"select * from 資料庫表名稱";
strSql+=pszTableNmae;                              //資料庫表名
m_pRecordset->Open(_bstr_t(strSql.c_str()),m_pConnection.GetInterfacePtr(), 
adOpenDynamic, adLockOptimistic, adCmdText);   //開啟記錄集
}
/************************************************
  函式名稱:FindData
  函式功能:根據條件查詢(SQL)
  輸入引數:
pszTableNmae  資料庫表名稱
pszWhereKey   欄位名(條件查詢的條件欄位)
pszValue      對應的記錄值(條件欄位值)
vecName       儲存容器
sql查詢語句如  "SELECT 欄位 FROM 員工表 WHERE ID='5'"
  輸出引數:
  void
*************************************************/
void CKpAdoDatabase::FindData(LPCSTR pszTableNmae,LPCSTR pszWhereKey,LPCSTR pszValue,vector<LPCSTR>& vecName)
{
CloseTable();//關閉開啟的表
    m_pRecordset.CreateInstance(__uuidof(Recordset));//例項化 
char szSql[MAX_PATH]={0};
sprintf(szSql,"SELECT * FROM %s WHERE %s='%s'",pszTableNmae,pszWhereKey,pszValue);
m_pRecordset->Open(_bstr_t(szSql),m_pConnection.GetInterfacePtr(), 
adOpenDynamic, adLockOptimistic, adCmdText);  //開啟記錄集
//獲取欄位
UINT nCount=m_pRecordset->Fields->GetCount();
m_pRecordset->MoveFirst();
while(TRUE){//獲取記錄集
string strTmp="";
for (long i=0;i<nCount;i++){//組合獲取的整條記錄
_bstr_t bstrName=m_pRecordset->Fields->GetItem(i)->GetValue();
if (strTmp.empty()){
strTmp+=(LPCSTR)bstrName;
}else{
strTmp+=",";
strTmp+=(LPCSTR)bstrName;
}
}
vecName.push_back(strTmp.c_str());
m_pRecordset->MoveNext();
if (IsEOF()){
break;
}
}
}
/************************************************
  函式名稱:GetrecordCount
  函式功能:獲取記錄集的數量
  輸入引數:
……
  輸出引數:
  ULONG
*************************************************/
ULONG CKpAdoDatabase:: GetrecordCount()
{
//獲取記錄集的數量
ULONG nCount=0;
//nCount=m_pRecordset->GetRecordCount();// 獲取記錄有問題
return nCount;
}


/************************************************
  函式名稱:GetFieldCount
  函式功能:獲取欄位的數量
  輸入引數:
……
  輸出引數:
  ULONG
*************************************************/
ULONG CKpAdoDatabase:: GetFieldCount()
{
//獲取欄位的數量
ULONG FCount=0;
FCount=m_pRecordset->Fields->GetCount();
return FCount;
}




/************************************************
  函式名稱:GetFieldInfo
  函式功能:獲取欄位名稱
  輸入引數:
nIndex  欄位Number
strName 得到的名稱
  輸出引數:
  BOOL
*************************************************/
BOOL CKpAdoDatabase:: GetFieldInfo(long nIndex,string& strName)
{
//獲取欄位的資訊
_bstr_t bstrName=m_pRecordset->Fields->GetItem(nIndex)->GetName();
     strName=(LPCSTR)bstrName;
return TRUE;
}
/************************************************
  函式名稱:GetFieldCollect
  函式功能:對應欄位的記錄值
  輸入引數:
nIndex  欄位Number
strName 得到的值
  輸出引數:
  BOOL
*************************************************/
BOOL CKpAdoDatabase:: GetFieldCollect(long nIndex,string& strName)
{
    //獲取記錄
_bstr_t bstrName=m_pRecordset->Fields->GetItem(nIndex)->GetValue();
strName=(LPCSTR)bstrName;
return TRUE;
}


/************************************************
  函式名稱:MoveNext
  函式功能:遊標向下
  輸入引數:
 
  輸出引數:
  void
*************************************************/
void CKpAdoDatabase::MoveNext()
{
m_pRecordset->MoveNext();
}
/************************************************
  函式名稱:MovePrevious
  函式功能:遊標向上
  輸入引數:
 
  輸出引數:
  void
*************************************************/
void CKpAdoDatabase::MovePrevious()
{
m_pRecordset->MovePrevious();
}
/************************************************
  函式名稱:MoveFirst
  函式功能:遊標到頭
  輸入引數:
 
  輸出引數:
  void
*************************************************/
void CKpAdoDatabase::MoveFirst()
{
if (!IsBOF()){
m_pRecordset->MoveFirst();
}
}
/************************************************
  函式名稱:MoveLast
  函式功能:遊標到尾
  輸入引數:
 
  輸出引數:
  void
*************************************************/
void CKpAdoDatabase::MoveLast()
{
if (!IsEOF()){
m_pRecordset->MoveLast();
}
}
/************************************************
  函式名稱:IsEOF
  函式功能:判斷遊標指標是否在記錄尾部
  輸入引數:
 
  輸出引數:
  BOOL
*************************************************/
BOOL CKpAdoDatabase::IsEOF()
{
//判斷遊標指標是否在記錄尾部
if(m_pRecordset->adoEOF){
return TRUE;
}
return FALSE;
}
/************************************************
  函式名稱:IsBOF
  函式功能:判斷遊標指標是否在記錄頭部
  輸入引數:
 
  輸出引數:
  BOOL
*************************************************/
BOOL CKpAdoDatabase:: IsBOF()
{
if(m_pRecordset->adoBOF){
return TRUE;
}
return FALSE;
}
/************************************************
  函式名稱:AddNew
  函式功能:新增新紀錄行
  輸入引數:
lnIndex 欄位Number(主鍵欄位)
Value    設定的值
  輸出引數:
  void
*************************************************/
void CKpAdoDatabase:: AddNew(LONG lnIndex,LPSTR Value)
{//新增記錄
m_pRecordset->AddNew();
m_pRecordset->Fields->GetItem(lnIndex)->Value=_bstr_t(Value);//設定主鍵欄位值
LONG ulCount=GetFieldCount();//獲取欄位的數量
for(LONG i=1;i<ulCount;i++){//設定其他為0
m_pRecordset->Fields->GetItem(i)->Value=_bstr_t("0");
}
}
/************************************************
  函式名稱:SetValue
  函式功能:設定欄位對應的記錄
  輸入引數:
lnIndex 欄位Number(主鍵欄位)
Value    設定的值
  輸出引數:
  void
*************************************************/
void CKpAdoDatabase::SetValue(LONG lnIndex,LPCSTR Value)
{//修改記錄
m_pRecordset->Fields->GetItem(lnIndex)->Value=_bstr_t(Value);
}
/************************************************
  函式名稱:Delete
  函式功能:刪除
  輸入引數:


  輸出引數:
  void
*************************************************/
void CKpAdoDatabase::Delete(_In_ int iIndex,_In_ int nCount/* = 1*/)
{
//m_pRecordset->Delete();
}
/************************************************
  函式名稱:Update
  函式功能:更新儲存記錄
  輸入引數:


  輸出引數:
  void
*************************************************/
void CKpAdoDatabase:: Update()
{//更新儲存記錄
m_pRecordset->Update(); 
}
/************************************************
  函式名稱:CloseTable
  函式功能:關閉表
  輸入引數:


  輸出引數:
  void
*************************************************/
void CKpAdoDatabase:: CloseTable()
{//關閉記錄集表
//if(m_pRecordset->State){}
if (NULL!=m_pRecordset){
m_pRecordset->Close();
}
}
/************************************************
  函式名稱:Close
  函式功能:關閉資料連線
  輸入引數:


  輸出引數:
  void
*************************************************/
void CKpAdoDatabase::Close()
{//關閉資料庫連線
if(m_pConnection!=NULL){
m_pConnection->Close();
m_pConnection.Release();
//::CoUninitialize();
}
}
/************************************************
  函式名稱:IsHaveFile
  函式功能:查詢檔案是否存在
  輸入引數:


  輸出引數:
  BOOL
*************************************************/
BOOL CKpAdoDatabase::IsHaveFile( LPSTR pszPath )
{
BOOL bFlag=FALSE;
WIN32_FIND_DATA find = { 0 };
HANDLE hFind = FindFirstFile( pszPath, &find );//開始查詢
BOOL bRet = TRUE;
while( TRUE == bRet )
{
if( !(find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ){
string strPathName=find.cFileName;
strPathName=strPathName.substr(strPathName.rfind(".")+1);
if(strPathName == "mdb"){
                bFlag=TRUE;
break;
}
}
bRet = FindNextFile( hFind, &find );
}
//關閉
FindClose( hFind );
return bFlag;
}


/************************************************
  函式名稱:CreateMdb
  函式功能:建立ACCESS資料庫和表
  輸入引數:
strDBName 資料庫路徑名稱
  輸出引數:
  BOOL
*************************************************/
BOOL CKpAdoDatabase::CreateMdb(string strMdbName)

if (!IsHaveFile((LPSTR)strMdbName.c_str())){
string strMdbConn = "Provider='Microsoft.JET.OLEDB.4.0';Data source =" + strMdbName;
try{
 HRESULT hr = S_OK; 
 _CatalogPtr pCatalog = NULL;
 _bstr_t cnnstring(strMdbConn.c_str());
 TESTHR(hr = pCatalog.CreateInstance(__uuidof (Catalog)));
pCatalog->Create(cnnstring);
}catch(_com_error e){
 _bstr_t bstrDescription(e.Description());
 string strErro=string("建立ACCEESS資料庫出錯: ") + (LPSTR)e.Description()
 + string("Create ACCESS DB error: ") + (LPSTR)e.Description();
 wstring strTmp;
 CKpString::ByteToWChar(strErro.c_str(),strTmp);
 MessageBoxW(NULL,strTmp.c_str(),L"",MB_OK);
 return FALSE;
}
}
 return TRUE;
}


/************************************************
  函式名稱:CreateTable
  函式功能:建立資料庫表
  輸入引數:
strMdbName 資料庫路徑
strTabName 表名
  輸出引數:
  BOOL
*************************************************/
BOOL CKpAdoDatabase::CreateTable(string strMdbName,string strTabName,vector<FIELDSINFO*>& vecFields)
{
HRESULT hr = S_OK;
_CatalogPtr pCatalog = NULL;
_TablePtr pTableNew = NULL;
_IndexPtr pIndexNew = NULL;
_IndexPtr pIndex  = NULL;
_ColumnPtr pColumn  = NULL;
if(!IsHaveFile((LPSTR)strMdbName.c_str())){
MessageBoxW(NULL,L"資料庫不存在,請先建立資料庫!",L"提示",MB_OK);
return FALSE;
}
string strConn="Provider='Microsoft.JET.OLEDB.4.0';Data source = " + strMdbName+";User ID=;Password="; 
_bstr_t strcnn(strConn.c_str());
try{//例項化指標
TESTHR(hr = pCatalog.CreateInstance (__uuidof(Catalog)));
TESTHR(hr = pTableNew.CreateInstance(__uuidof(Table)));
TESTHR(hr = pIndexNew.CreateInstance(__uuidof(Index)));
TESTHR(hr = pIndex.CreateInstance   (__uuidof(Index)));
TESTHR(hr = pColumn.CreateInstance  (__uuidof(Column)));
pCatalog->PutActiveConnection(strcnn);// 連線
pTableNew->Name = _bstr_t(strTabName.c_str());// 表名
pTableNew->ParentCatalog = pCatalog;
// 加入欄位
for(int i=0;i<vecFields.size();i++){
//(adVarWChar)為文字型別 (adLongVarWChar)為備註型別
pTableNew->Columns->Append(_variant_t(vecFields[i]->strFieldsName.c_str()), ADOCG::adLongVarWChar,255);
//將必填欄位設定為false
pTableNew->Columns->GetItem(_variant_t(vecFields[i]->strFieldsName.c_str()))->Properties->GetItem("Jet OLEDB:Allow Zero Length")->Value =vecFields[i]->IsSetZero; 
if (vecFields[i]->IsSetPrimaryKey){// 加入主鍵
pIndexNew->Name = "pryIndex";//"日期";
pIndexNew->Columns->Append(_variant_t(vecFields[i]->strFieldsName.c_str()), ADOCG::adLongVarWChar, 255);
pIndexNew->PutPrimaryKey(1);//-1表示設定主鍵 1表示不設主鍵 如:pIndexNew->PutPrimaryKey(-1);
pIndexNew->PutUnique(1);//-1表示設定主鍵 1表示不設主鍵 如:pIndexNew->PutUnique(-1);
pTableNew->Indexes->Append(_variant_t ((IDispatch*)pIndexNew));
}
}
// 加入表中
pCatalog->Tables->Append(_variant_t ((IDispatch*)pTableNew));        
pCatalog->Tables->Refresh();
}catch(_com_error &e){
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
return FALSE;
}
return TRUE;
}