明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

封裝ADO訪問(wèn)數(shù)據(jù)庫(kù)的2個(gè)類

[摘要]對(duì)于初學(xué)者,使用ADO訪問(wèn)數(shù)據(jù)庫(kù)的時(shí)候,涉及到各種數(shù)據(jù)類型轉(zhuǎn)換,可能有一些難度,我試圖封裝了ADO訪問(wèn)數(shù)據(jù)庫(kù),使其更方便的用現(xiàn)有的VC的數(shù)據(jù)類型,更加方便的使用ADO操作數(shù)據(jù)庫(kù)。下面分別提供兩個(gè)封裝ADO數(shù)據(jù)庫(kù)訪問(wèn)的類,一個(gè)是數(shù)據(jù)庫(kù)的連接類,一個(gè)是數(shù)據(jù)庫(kù)字段訪問(wèn)的類。 在連接類中,大家可以看到...
    對(duì)于初學(xué)者,使用ADO訪問(wèn)數(shù)據(jù)庫(kù)的時(shí)候,涉及到各種數(shù)據(jù)類型轉(zhuǎn)換,可能有一些難度,我試圖封裝了ADO訪問(wèn)數(shù)據(jù)庫(kù),使其更方便的用現(xiàn)有的VC的數(shù)據(jù)類型,更加方便的使用ADO操作數(shù)據(jù)庫(kù)。
下面分別提供兩個(gè)封裝ADO數(shù)據(jù)庫(kù)訪問(wèn)的類,一個(gè)是數(shù)據(jù)庫(kù)的連接類,一個(gè)是數(shù)據(jù)庫(kù)字段訪問(wèn)的類。

   在連接類中,大家可以看到,連接類中并沒(méi)有Recordset的成員變量,因?yàn)檫@樣的,在整個(gè)數(shù)據(jù)庫(kù)應(yīng)用程序中,數(shù)據(jù)庫(kù)的連接一般一個(gè)就夠了,而同時(shí)打開(kāi)的Reocordset則可能不只一個(gè),所以,如果兩個(gè)在同一個(gè)類里,那么,如果要同時(shí)打開(kāi)兩個(gè)記錄集,需要建立類的兩個(gè)實(shí)例,就是需要同時(shí)打開(kāi)兩個(gè)數(shù)據(jù)庫(kù)連接,如果對(duì)于連接的是同一個(gè)數(shù)據(jù)庫(kù),同時(shí)打開(kāi)兩個(gè)連接的話,意味著資源的不必要的浪費(fèi)。

   數(shù)據(jù)庫(kù)字段訪問(wèn)類,簡(jiǎn)化了,獲取數(shù)據(jù)庫(kù)字段內(nèi)容的操作,避免了數(shù)據(jù)類型轉(zhuǎn)換的麻煩。

   兩個(gè)類都對(duì)錯(cuò)誤處理進(jìn)行了較多的考慮,在訪問(wèn)數(shù)據(jù)庫(kù)中,如果沒(méi)有錯(cuò)誤處理,其害處是顯而易見(jiàn)的。




#ifndef _BBADOCONNECT_H
#define _BBADOCONNECT_H

//
// ADO訪問(wèn)數(shù)據(jù)庫(kù)類
// 軟件環(huán)境:需要MSADO15.DLL
// 作者:鄧振波
// 2001.4.20
// Email:bozi@china.com
// 說(shuō)明:封裝了ADO使用的操作函數(shù)和ADO訪問(wèn)數(shù)據(jù)庫(kù)錯(cuò)誤處理
//  使在VC上方便的使用ADO訪問(wèn)數(shù)據(jù)庫(kù)
// 包括:ADO連接數(shù)據(jù)庫(kù)、打開(kāi)記錄集、執(zhí)行SQL、以及
//  事務(wù)處理、ADO記錄集內(nèi)容轉(zhuǎn)換成C++的常用數(shù)據(jù)類型(CString、char,long,float等)
//
// 使用:1。定義一個(gè)CBBAdoConnection實(shí)例:CBBAdoConnection m_adoConn;
//  2。建立連接:m_adoConn.Open(strConnstring);
//     如果需要無(wú)條件重新連接的可以,參數(shù)bRepen設(shè)成TREU
//  3。打開(kāi)記錄集:
//
//   _RecordsetPtr* prsThis=NULL;
//   prsThis=new _RecordsetPtr;
//   CString strSQL;
//   strSQL="select * from Table_Name";//  
//   如果記錄集打開(kāi)失敗
//   

if(!(m_adoConn.OpenRecordset(strSQL,prsThis)))
//    return FALSE;
//  4。建立記錄集值對(duì)象
//   注意需要用參數(shù)構(gòu)造
//   CBBRstValues rsv(m_adoConn,prsThis);
//  
//  5。獲得的字段的值
//   rsv.GetValueLong(&m_nDeptID,1L);//獲得第一個(gè)字段的值
//   rsv.GetValueStr(m_strName,"ID");//獲得第一個(gè)字段名為ID的值
//   其它的同理.如果需要獲得SQL Server中nText類型的字段值請(qǐng)用
//   GetValText(CString &strText, CString &strFieldName)函數(shù)
//  6。記錄集的記錄移動(dòng) (*prsThis)->MoveNext()等類似函數(shù)
//  7。記錄集不用時(shí)候需要釋放其資源
//   1)關(guān)閉記錄集
//   2)刪除記錄集指針
//   e.g. (*prsThis)->Close();
//     delete prsThis;
//     prsThis=NULL;
//   否則會(huì)造成內(nèi)存泄漏
//  
//  注:
//   1。程序必須要初始化COM環(huán)境,請(qǐng)?jiān)趹?yīng)用類中加入AfxOleInit函數(shù)初始化環(huán)境,否則ADO的調(diào)用將失敗
//   2。如果需要調(diào)用存儲(chǔ)過(guò)程SQL語(yǔ)句改為“Exec ” + 存儲(chǔ)過(guò)程名即可,與執(zhí)行SQL同樣
//
//                 CopyRight seesi,2001
//
//      說(shuō)明:你可以隨便在的程序中任意使用、修改本代碼,但請(qǐng)你不要?jiǎng)h除文件頭的部分說(shuō)明。如果需要轉(zhuǎn)載,請(qǐng)注明出處。
// msado15.dll必須放在本文件所在目錄,或者自己指定下面的msado15.dll全路徑
//

#if !defined(__AFXADO_H)
#import "msado15.dll" no_namespace rename ("EOF", "adoEOF") \
  rename ("LockTypeEnum", "adoLockTypeEnum") \
  rename ("DataTypeEnum", "adoDataTypeEnum") \
  rename ("FieldAttributeEnum",

"adoFieldAttributeEnum") \
  rename ("EditModeEnum", "adoEditModeEnum") \
  rename ("RecordStatusEnum", "adoRecordStatusEnum")

\
  rename ("ParameterDirectionEnum",

"adoParameterDirectionEnum")
#endif  // !defined(__AFXADO_H)


class CBBAdoConnection  
{
public:
CBBAdoConnection();
virtual ~CBBAdoConnection();
public:
int SetConnTimeOut(long lTimeOut); // 設(shè)置連接超時(shí)
int SetCommTimeOut(long lTimeOut); // 設(shè)置命令執(zhí)行超時(shí)
BOOL IsConnectClose(); // 判斷連接是否已經(jīng)打開(kāi)
int ExecuteSQL(LPCSTR szSQL); // 簡(jiǎn)單執(zhí)行SQL語(yǔ)句,不返回記錄集
// 打開(kāi)數(shù)據(jù)庫(kù)記錄集
// 參數(shù):
//  strSQL  記錄集的SQL語(yǔ)句
//  rs   返回的記錄集_RecordsetPtr對(duì)象
//  sConnString 數(shù)據(jù)庫(kù)的連接字符串
//     如果使用數(shù)據(jù)庫(kù)連接已經(jīng)打開(kāi),參數(shù)沒(méi)用
//     如果數(shù)據(jù)庫(kù)的連接沒(méi)有打開(kāi),當(dāng)給予一個(gè)連接字符串,將先打開(kāi)數(shù)據(jù)庫(kù)連接
BOOL OpenRecordset(CString strSQL, _RecordsetPtr *rs,CString sConnString="");//打開(kāi)數(shù)據(jù)庫(kù)記錄集
BOOL OpenRecordset(const char *sSQL,_RecordsetPtr* rs,char* sConnString=NULL);

// 打開(kāi)數(shù)據(jù)庫(kù)連接
// 參數(shù):
//  strConnString 連接字符串
//  sConnString  連接字符串
//  bReOpen   是否重新打開(kāi),如果為FALSE,,
//      將先判斷數(shù)據(jù)庫(kù)是否打開(kāi)如果沒(méi)有打開(kāi)則打開(kāi),
//      如果已經(jīng)打開(kāi),將不執(zhí)行任何操作
//      如果為TRUE,則無(wú)條件重新打開(kāi)。
BOOL OpenConnection(CString strConnString ,BOOL bReOpen=FALSE);
BOOL OpenConnection(char* sConnString,BOOL bReOpen=FALSE); void CloseConnect();// 關(guān)閉數(shù)據(jù)庫(kù)連接

BOOL ExecuteTrans(CStringArray arrStrSQL); // 事務(wù)處理,不返回任何記錄集,參數(shù)為事務(wù)SQL數(shù)組


_ConnectionPtr* GetConnection(); // 得到_ConnectionPtr指針
CString GetConnString(); // 得到連接字符串
private:
enum ERRORFrom {
     ErrFormOpenConnsction,
     ErrFromOpenRecordset,
     ErrFormCloseConnection,
     ErrFormTanslation
     };
_ConnectionPtr* m_pConn;
char m_szConnString[512];
///
protected:
void ReportError(int nERRORfrom);
};


class CBBRstValues  
{
public:
// 三種構(gòu)造類的方法
// 如果無(wú)參數(shù)構(gòu)造,請(qǐng)構(gòu)造后調(diào)用InitConnectAndRst方法
// 其他的兩種構(gòu)造則不需調(diào)用InitConnectAndRst方法
CBBRstValues();
CBBRstValues(_ConnectionPtr* pConn,_RecordsetPtr* pRs);
CBBRstValues(CBBAdoConnection* pBBadoConn,_RecordsetPtr*

pRs);

virtual ~CBBRstValues();
public:
// 初始化連接隊(duì)象和記錄集對(duì)象
void InitConnectAndRst(_ConnectionPtr* pConn,_RecordsetPtr*  pRs);
void InitConnectAndRst(CBBAdoConnection* pBBAdoConn, _RecordsetPtr *  Rs);

// GetValText函數(shù)
// 得到數(shù)據(jù)庫(kù)nText字段的值
// 參數(shù):
//  strText   用來(lái)接收返回值(字段值)
//  strFieldName 字段名,該字段數(shù)據(jù)類型必須是nText類型
BOOL GetValText(CString& strText,CString& strFieldName); //得到數(shù)據(jù)庫(kù)nText字段的值

// GetValueStr函數(shù)
// 得到數(shù)字型,日期型和字符型字段值函數(shù)
// 參數(shù):
//  cVal   用來(lái)接收返回值(字段值)的字符串指針,要求要開(kāi)辟足夠的內(nèi)存單元
//      或者足夠容納字段內(nèi)容的字符數(shù)組。
//  vIndex   數(shù)據(jù)庫(kù)字段的名字或者索引,變體型,一般不直接用這個(gè)參數(shù),
//      應(yīng)該用同形式的多態(tài)函數(shù)的參數(shù)調(diào)用
//      數(shù)據(jù)庫(kù)字段的數(shù)據(jù)類型可以是數(shù)字型,日期型和字符型
//  nFieldLen  需要返回的數(shù)據(jù)的字符串的長(zhǎng)度,如果為-1,則返回整個(gè)字段值
//  lpszFieldName 字段名,數(shù)據(jù)庫(kù)字段的數(shù)據(jù)類型可以是數(shù)字型,日期型和字符型
//  nFieldIndex  在SQL語(yǔ)句中字段的索引序號(hào)數(shù)據(jù)庫(kù)字段的數(shù)據(jù)類型可以是數(shù)字型,日期型和字符型

// GetValueLong函數(shù)
// 得到數(shù)字型,日期型和字符型字段值函數(shù)
// 參數(shù):
//  lVal   用來(lái)接收返回值(字段值)
//  vIndex   數(shù)據(jù)庫(kù)字段的名字或者索引,變體型,一般不直接用這個(gè)參數(shù),
//      應(yīng)該用同形式的多態(tài)函數(shù)的參數(shù)調(diào)用
//      數(shù)據(jù)庫(kù)字段的數(shù)據(jù)類型要求是數(shù)字型(int,long)
//  lpszFieldName 字段名,數(shù)據(jù)庫(kù)字段的數(shù)據(jù)類型可以是數(shù)字型,日期型和字符型
//  nFieldIndex  在SQL語(yǔ)句中字段的索引序號(hào)數(shù)據(jù)庫(kù)字段的數(shù)據(jù)類型可以是數(shù)字型,日期型和字符型

// GetValueFlaot函數(shù)
// 得到數(shù)字型,日期型和字符型字段值函數(shù)
// 參數(shù):
//  fVal   用來(lái)接收返回值(字段值)
//  vIndex   數(shù)據(jù)庫(kù)字段的名字或者索引,變體型,一般不直接用這個(gè)參數(shù),
//      應(yīng)該用同形式的多態(tài)函數(shù)的參數(shù)調(diào)用
//      數(shù)據(jù)庫(kù)字段的數(shù)據(jù)類型要求是字型(int,long,float,貨幣型等)
//  lpszFieldName 字段名,數(shù)據(jù)庫(kù)字段的數(shù)據(jù)類型可以是數(shù)字型,日期型和字符型
//  nFieldIndex  在SQL語(yǔ)句中字段的索引序號(hào)數(shù)據(jù)庫(kù)字段的數(shù)據(jù)類型可以是數(shù)字型,日期型和字符型

BOOL GetValueStr(char* cVal,_variant_t &vIndex,int

nFieldLen=-1);
BOOL GetValueLong(long* lVal,_variant_t &vIndex);
BOOL GetValueFloat(float* fVal,_variant_t &vIndex);

BOOL GetValueStr(char* cVal,long lIndex,int nFieldLen=-1);
BOOL GetValueLong(long* lVal,long lIndex);
BOOL GetValueFloat(float* fVal,long lIndex);

BOOL GetValueStr(char* cVal,CString strIndex,int nFieldLen=-1);
GetValueLong(long *lVal, LPCSTR lpszIndex);
BOOL GetValueFloat(float* fVal,CString strIndex);

BOOL GetValueStr(CString& str,LPCSTR lpszFieldName,int nFieldLen=-1);
BOOL GetValueStr(CString& str,UINT nFieldIndex,int nFieldLen=-1);
BOOL GetValueStr(CString& str,_variant_t &vIndex,int nFieldLen=-1);

// 判斷值是否有效,是否為NULL
BOOL VerifyVTData(_variant_t& value);
BOOL VerifyVTData(char* pData);
protected:
_RecordsetPtr* m_prsThis;
_ConnectionPtr* m_pConn;
void ReportError();

};

#endif // _BBADOCONNECT_H







////CPP文件

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBBAdoConnection::CBBAdoConnection()
{
   m_pConn=NULL;
}

_ConnectionPtr* CBBAdoConnection::GetConnection()
{
return m_pConn;
}

CString CBBAdoConnection::GetConnString()
{
return m_szConnString;
}

CBBAdoConnection::~CBBAdoConnection()
{
// 關(guān)比連接
CloseConnect();
}

BOOL CBBAdoConnection::OpenConnection(char *sConnString,BOOL bReOpen /*=FALSE*/)
{

// 不需重新打開(kāi)
if(!bReOpen)
{
  if(m_pConn !=NULL && ((*m_pConn)->State!=adStateClosed))
   return TRUE;  
}

VERIFY(sConnString);
strcpy(m_szConnString,sConnString);

try
{
  m_pConn =new _ConnectionPtr;
  m_pConn->CreateInstance(__uuidof(Connection));
  if(m_pConn==NULL)
   return FALSE;
  HRESULT hr=(*m_pConn)->Open((char*)sConnString,"","",-1);  
  if(FAILED(hr))
   return FALSE;  
  return TRUE;
}
catch(_com_error)
{
  ReportError(ErrFormOpenConnsction);
  return FALSE;
}
catch(...)
{
  #ifdef _DEBUG // 調(diào)試時(shí)顯示相應(yīng)的錯(cuò)誤信息
   MessageBox(NULL,"數(shù)據(jù)庫(kù)連接未處理的異常!","連接失敗",MB_OK MB_ICONINFORMATION);
  #else
   MessageBox(NULL,"連接數(shù)據(jù)失敗,請(qǐng)檢查網(wǎng)絡(luò)和數(shù)據(jù)庫(kù)設(shè)置是否正確","連接失敗",MB_OK MB_ICONINFORMATION);
  #endif
  return FALSE;
}
SetConnTimeOut(5);
}

BOOL CBBAdoConnection::OpenRecordset(const char *sSQL, _RecordsetPtr *rs, char *sConnString)
{
// rs=new _RecordsetPtr;
VERIFY(sSQL);
try
{  

  if((m_pConn==NULL) ((*m_pConn)->State==adStateClosed))
  {
   int n=(*m_pConn)->State;
   if(sConnString!=NULL)
   {
    if(!OpenConnection(sConnString))
     return FALSE;
   }
   // 嘗試連接數(shù)據(jù)庫(kù)
   else
   {
    //
    // if(!OpenConnection(m_szConnString))
    // return FALSE;
    // MessageBox(NULL,"數(shù)據(jù)庫(kù)連接已經(jīng)斷開(kāi),請(qǐng)重新連接!","連接問(wèn)題",MB_OK MB_ICONINFORMATION);  
   }

   return FALSE;
  }  
  // rs=new _RecordsetPtr;
  HRESULT hr;
  hr=rs->CreateInstance(__uuidof(Recordset));
  if(FAILED(hr))
  {   
   return FALSE;// 建立實(shí)例失敗
  }     
  hr=(*rs)->Open(sSQL,m_pConn->GetInterfacePtr(),
   adOpenStatic, adLockBatchOptimistic, -1);
  if(FAILED(hr))
  {   
   return FALSE;// 打開(kāi)連接失敗
  }   
  return TRUE;// 成功返回
}
catch(_com_error)
{
  
  // AfxMessageBox(ce->Description());
  ReportError(ErrFromOpenRecordset);
  return FALSE;
}
catch(...)
{
  MessageBox(NULL,"數(shù)據(jù)庫(kù)記錄打開(kāi)失!","記錄失敗",MB_OK MB_ICONINFORMATION);
  return FALSE;
}
return TRUE;
}

void CBBAdoConnection::CloseConnect()
{
try
{
  if(m_pConn!=NULL)
  {
   if((*m_pConn)->State!=adStateClosed)
    (*m_pConn)->Close();   
   delete m_pConn;
   m_pConn=NULL;
  }
}
catch(_com_error)
{
  ReportError(ErrFormCloseConnection);
}
catch(...)
{
  AfxMessageBox("關(guān)閉數(shù)據(jù)庫(kù)連接未知錯(cuò)誤!");
}
}





BOOL CBBAdoConnection::OpenConnection(CString strConnString, BOOL bReOpen)
{
char c[512];
strcpy(c,strConnString.GetBuffer(0));
strConnString.ReleaseBuffer();
return OpenConnection(c,bReOpen);
}

BOOL CBBAdoConnection::OpenRecordset(CString strSQL, _RecordsetPtr *rs, CString sConnString)
{
char c[1024];
strcpy(c,strSQL.GetBuffer(0));
strSQL.ReleaseBuffer();
return OpenRecordset(c,rs,(char*)(LPCTSTR)sConnString);
}

BOOL CBBAdoConnection::ExecuteTrans(CStringArray arrStrSQL) // 開(kāi)始事務(wù)處理,不返回任何記錄集,參數(shù)為事務(wù)SQL數(shù)組
{

(*m_pConn)->BeginTrans();

try
{
  _RecordsetPtr* prsThis;
  for(int i=0;i<arrStrSQL.GetSize();i++)
  {
   prsThis=new _RecordsetPtr;   
   OpenRecordset(arrStrSQL.ElementAt(i),prsThis);
   delete prsThis;
  }
  prsThis=NULL;
  (*m_pConn)->CommitTrans();
  return TRUE;
}
catch(_com_error)
{
  (*m_pConn)->RollbackTrans();
  ReportError(ErrFormTanslation);
  return FALSE;
}
}




// 執(zhí)行SQL操作,不返回記錄集
int CBBAdoConnection::ExecuteSQL(LPCSTR szSQL)
{
// VARIANT vEffect;
try
{
  (*m_pConn)->Execute(szSQL,NULL,adCmdText adExecuteNoRecords);
  return TRUE;
}
catch(_com_error)
{
  ReportError(ErrFormTanslation);    
  return FALSE;
}
// return vEffect.lVal;
}

// 返回是否處在連接狀態(tài)
BOOL CBBAdoConnection::IsConnectClose()
{

return (m_pConn==NULL) ((*m_pConn)->State==adStateClosed);
}

// 設(shè)置連接超時(shí)
int CBBAdoConnection::SetConnTimeOut(long lTimeOut)
{
return (*m_pConn)->put_ConnectionTimeout(lTimeOut);
}

int CBBAdoConnection::SetCommTimeOut(long lTimeOut)
{
return (*m_pConn)->put_CommandTimeout(lTimeOut);
}

// 報(bào)告錯(cuò)誤
void CBBAdoConnection::ReportError(int nERRORfrom)
{
switch(nERRORfrom)
{
case ErrFormOpenConnsction:
  #ifdef _DEBUG  // 調(diào)試試時(shí)顯示相應(yīng)的錯(cuò)誤信息
   try
   {
    for(long l=0;l<(*m_pConn)->Errors->Count;l++)
    {
     ErrorPtr pErr;
     pErr=(*m_pConn)->Errors->GetItem(l);
     CString str;
     str=(char*)pErr->Description;     
     MessageBox(NULL,str,"連接失敗",MB_OK MB_ICONINFORMATION);
    }
   }
   catch(...)
   {
    MessageBox(NULL,"數(shù)據(jù)庫(kù)連接未知錯(cuò)誤,無(wú)法捕捉具體錯(cuò)誤信息!","錯(cuò)誤",MB_ICONINFORMATION);
   }
  #else
    MessageBox(NULL,"連接數(shù)據(jù)失敗,請(qǐng)檢查網(wǎng)絡(luò)和數(shù)據(jù)庫(kù)設(shè)置是否正確","連接失敗",MB_OK MB_ICONINFORMATION);
  #endif
  break;
case ErrFromOpenRecordset:
  #ifdef _DEBUG
    try
    {    
     for(long i=0;i<(*m_pConn)->Errors->Count;i++)
     {
      ErrorPtr pErr;
      pErr=(*m_pConn)->Errors->GetItem(i);
      AfxMessageBox(pErr->Description);
     }
    }
    catch(...)
    {
     MessageBox(NULL,"數(shù)據(jù)庫(kù)連接未知錯(cuò)誤,無(wú)法捕捉具體錯(cuò)誤信息!","錯(cuò)誤",MB_ICONINFORMATION);
    }
  #else
    MessageBox(NULL,"打開(kāi)數(shù)據(jù)庫(kù)失敗,請(qǐng)檢查網(wǎng)絡(luò),并嘗試重新連接數(shù)據(jù)庫(kù)!","記錄失敗",MB_OK MB_ICONINFORMATION);
  #endif
  break;
case ErrFormCloseConnection:
  #ifdef _DEBUG  // 調(diào)試時(shí)顯示相應(yīng)的錯(cuò)誤信息
   try
   {
    for(long l=0;l<(*m_pConn)->Errors->Count;l++)
    {
     ErrorPtr pErr;
     pErr=(*m_pConn)->Errors->GetItem(l);
     CString str;
     str=(char*)pErr->Description;
     MessageBox(NULL,str,"連接失敗",MB_OK MB_ICONINFORMATION);
    }
   }
   catch(...)
   {
    MessageBox(NULL,"數(shù)據(jù)庫(kù)連接未知錯(cuò)誤,無(wú)法捕捉具體錯(cuò)誤信息!","錯(cuò)誤",MB_ICONINFORMATION);
   }

  #else
    ;// MessageBox(NULL,"關(guān)閉數(shù)據(jù)庫(kù)連接異常","關(guān)閉異常",MB_OK MB_ICONINFORMATION);
  #endif
  break;
case ErrFormTanslation:
  #if def _DEBUG
   try
   {
    for(long i=0;i<(*m_pConn)->Errors->Count;i++)
    {
     ErrorPtr pErr;
     pErr=(*m_pConn)->Errors->GetItem(i);
     AfxMessageBox(pErr->Description);
    }
   }
   catch(...)
   {
    MessageBox(NULL,"數(shù)據(jù)庫(kù)連接未知錯(cuò)誤,無(wú)法捕捉具體錯(cuò)誤信息!","錯(cuò)誤",MB_ICONINFORMATION);
   }
  #else
    MessageBox(NULL,"數(shù)據(jù)庫(kù)執(zhí)行任務(wù)失敗,請(qǐng)檢查數(shù)據(jù)庫(kù)。","任務(wù)失敗",MB_OK MB_ICONINFORMATION);
  #endif
  break;
default:
  break;
}
}





/////////////// CRecordsetValus


CBBRstValues::CBBRstValues()
{
;
}

CBBRstValues::CBBRstValues(_ConnectionPtr* pConn,_RecordsetPtr* pRs)
{
ASSERT(pConn);
ASSERT(pRs);
m_prsThis=pRs;
m_pConn=pConn;
}

CBBRstValues::CBBRstValues(CBBAdoConnection* pBBadoConn,_RecordsetPtr* pRs)
{
CBBRstValues(pBBadoConn->GetConnection(),pRs);
}

CBBRstValues::~CBBRstValues()
{
;
}

void CBBRstValues::InitConnectAndRst(_ConnectionPtr *pConn, _RecordsetPtr *pRs)
{
ASSERT(pConn);
ASSERT(pRs);
m_prsThis=pRs;
m_pConn=pConn;
}

void CBBRstValues::InitConnectAndRst(CBBAdoConnection *pBBAdoConn, _RecordsetPtr *pRs)
{
InitConnectAndRst(pBBAdoConn->GetConnection(),pRs);
}

BOOL CBBRstValues::GetValueLong(long *lVal, _variant_t &vIndex)
{
_variant_t value;
try{

  if((*m_prsThis)==NULL (*m_prsThis)->State==adStateClosed)  
  {

#ifdef _DEBUG
   AfxMessageBox("記錄集未打開(kāi)!");
#else
   MessageBox(NULL,"無(wú)法讀取數(shù)據(jù)庫(kù)資料,可能數(shù)據(jù)庫(kù)連接已經(jīng)斷開(kāi),請(qǐng)重新連接、然后重試。","連接問(wèn)題",MB_ICONINFORMATION);
#endif
   return FALSE;
  }

  if((*m_prsThis)->adoEOF)
  {
   lVal=0;
   return FALSE;
  }

  value=(*m_prsThis)->GetCollect(vIndex);  
}
catch(_com_error)
{
  ReportError();
  return FALSE;
}
catch(...)
{
  AfxMessageBox("數(shù)據(jù)庫(kù)字段訪問(wèn)未知錯(cuò)誤!請(qǐng)檢查數(shù)據(jù)庫(kù)是否改動(dòng)。",MB_ICONINFORMATION);
  return FALSE;
}

if(VerifyVTData(value))  
{
  *lVal = long(value);
}
else
{
  *lVal=0;
}

return TRUE;
}

BOOL CBBRstValues::GetValueStr(char *cVal, _variant_t &vIndex, int nFieldLen)
{
char * c=NULL;
_variant_t value;
DATE dt;
CString str;
COleDateTime da;

// 檢查是數(shù)組
// VERIFY(sizeof(cVal)<1);
memset(cVal,0,sizeof(cVal));
try
{
  if((*m_prsThis)==NULL (*m_prsThis)->State==adStateClosed)
  {
#ifdef _DEBUG
   AfxMessageBox("記錄集未打開(kāi)!");
#else
   MessageBox(NULL,"無(wú)法讀取數(shù)據(jù)庫(kù)資料,可能數(shù)據(jù)庫(kù)連接已經(jīng)斷開(kāi),請(qǐng)重新連接、然后重試。","連接問(wèn)題",MB_ICONINFORMATION);
#endif
   return FALSE;
  }

  if((*m_prsThis)->adoEOF)
  {
   cVal[0]='\0';
   return FALSE;
  }
  value = (*m_prsThis)->GetCollect(vIndex);
}
catch(_com_error)
{
  ReportError();
  // AfxMessageBox("數(shù)據(jù)庫(kù)字段訪問(wèn)錯(cuò)誤!");
  return FALSE;
}
catch(...)
{
  AfxMessageBox("數(shù)據(jù)庫(kù)字段訪問(wèn)未知錯(cuò)誤!請(qǐng)檢查數(shù)據(jù)庫(kù)是否改動(dòng)。",MB_ICONINFORMATION);
  return FALSE;
}

if(VerifyVTData(value))
{
  switch(value.vt)
  {
   case VT_BSTR:
    c = (char *)_com_util::ConvertBSTRToString( V_BSTR(&value) );
    if(VerifyVTData(c))
    {           
     if(nFieldLen<=0)
     {
      strcpy(cVal,(char*)c);
     }
     else
     {
      strncpy(cVal, (char*)c, nFieldLen);
     }    
    }
    delete c;
    c=NULL;
    break;
   case VT_I4:
   case VT_DECIMAL:  
   case VT_UI4:
   case VT_I8:
   case VT_UI8:
   case VT_INT:
   case VT_UINT:
    long lVal;
    lVal = long(value);
    ltoa(lVal,cVal,10);    
    break;
   case VT_DATE:    
    dt=value.date;
    da=COleDateTime(dt);    
    // str=da.Format("%Y-%m-%d %H:%M:%S");
    str=da.Format("%Y-%m-%d ");
    c=new char[64];
    memset(c,0,sizeof(char)*64);
    strcpy(c,str.GetBuffer(0));
    str.ReleaseBuffer();
    if(VerifyVTData(c))
    {           
     if(nFieldLen<=0)
     {
      strcpy(cVal,(char*)c);
     }
     else
     {
      strncpy(cVal, (char*)c, nFieldLen);
      cVal[nFieldLen]='\0';
     }    
    }
    delete c;
    c=NULL;
    break;
   default:
#ifdef _DEBUG
    AfxMessageBox("未處理的字段數(shù)據(jù)類型,請(qǐng)?zhí)幚恚?quot;);
#else
    break;
#endif
    break;
  }
}

else
{
  cVal[0]='\0';
}
return TRUE;
}

BOOL CBBRstValues::GetValueLong(long *lVal, long lIndex)
{
_variant_t vIndex(lIndex);
return GetValueLong(lVal,vIndex);
}

BOOL CBBRstValues::GetValueLong(long *lVal, LPCSTR lpszIndex)
{
_variant_t vIndex(lpszIndex);
return GetValueLong(lVal,vIndex);
}

BOOL CBBRstValues::VerifyVTData(char *pData)
{
if(pData == NULL)
{
  return FALSE;
}
return TRUE;
}

BOOL CBBRstValues::VerifyVTData(_variant_t &value)
{
if(value.vt == VT_NULL)
{
  return FALSE;
}
return TRUE;
}

BOOL CBBRstValues::GetValueStr(CString& str,LPCSTR lpszFieldName,int nFieldLen/*=-1*/)
{
_variant_t vIndex(lpszFieldName);
return GetValueStr(str,vIndex,nFieldLen);
}

BOOL CBBRstValues::GetValueStr(CString& str,UINT nFieldIndex,int nFieldLen/*=-1*/)
{
_variant_t vIndex((long)nFieldIndex);  
return GetValueStr(str,vIndex,nFieldLen);

}

BOOL CBBRstValues::GetValueStr(CString& str,_variant_t &vIndex,int nFieldLen/*=-1*/)
{
TCHAR buffer[1024];
if(nFieldLen > 1023)
  nFieldLen = 1023;

BOOL bResult=GetValueStr((char*)buffer,vIndex,nFieldLen);
str.Format(buffer);
str.TrimRight();
return bResult;
}

BOOL CBBRstValues::GetValueFloat(float* fVal,_variant_t &vIndex)
{
_variant_t value;
try
{
  if((*m_prsThis)==NULL (*m_prsThis)->State==adStateClosed)
  {
  
#ifdef _DEBUG
   AfxMessageBox("記錄集未打開(kāi)!");
#else
   MessageBox(NULL,"無(wú)法讀取數(shù)據(jù)庫(kù)資料,可能數(shù)據(jù)庫(kù)連接已經(jīng)斷開(kāi),請(qǐng)重新連接、然后重試。","連接問(wèn)題",MB_ICONINFORMATION);
#endif
   return FALSE;
  }
  
  if((*m_prsThis)->adoEOF)
  {
   fVal=0;
   return FALSE;
  }

  value=(*m_prsThis)->GetCollect(vIndex);   
}
catch(_com_error)
{  
  ReportError();
  return FALSE;
}
catch(...)
{
  AfxMessageBox("數(shù)據(jù)庫(kù)字段訪問(wèn)未知錯(cuò)誤!請(qǐng)檢查連接數(shù)據(jù)庫(kù)結(jié)構(gòu)是否已經(jīng)更改。",MB_ICONINFORMATION);
  return FALSE;
}

if(VerifyVTData(value))
{
  *fVal = float(value);
}
else
{
  *fVal = 0;
}
return TRUE;
}


BOOL CBBRstValues::GetValueFloat(float* fVal,long lIndex)
{
_variant_t vIndex(lIndex);
return GetValueFloat(fVal,vIndex);
}

BOOL CBBRstValues::GetValueFloat(float* fVal,CString  strIndex)
{
_variant_t vIndex(strIndex);
return GetValueFloat(fVal,vIndex);
}

BOOL CBBRstValues::GetValueStr(char *cVal,long lIndex,int nFieldLen)
{
_variant_t vIndex;
vIndex=_variant_t(lIndex);
return GetValueStr(cVal,vIndex);
}


BOOL CBBRstValues::GetValueStr(char *cVal,CString strIndex,int nFieldLen)
{
_variant_t vIndex;
vIndex=_variant_t(strIndex);
return GetValueStr(cVal,vIndex);
}


void CBBRstValues::ReportError()
{
#ifdef _DEBUG
try
{
  for(long l=0;l<(*m_pConn)->Errors->Count;l++)
  {
   ErrorPtr pErr;
   pErr=(*m_pConn)->Errors->GetItem(l);
   AfxMessageBox(pErr->Description);
  }  
}
catch(...)
{
  AfxMessageBox("字段錯(cuò)誤對(duì)象訪問(wèn)錯(cuò)誤,請(qǐng)檢查書(shū)寫是否正確。");
}
#else
MessageBox(NULL,"字段訪問(wèn)發(fā)生錯(cuò)誤,請(qǐng)確認(rèn)數(shù)據(jù)庫(kù)結(jié)構(gòu)沒(méi)有改動(dòng)。","字段訪問(wèn)",MB_ICONINFORMATION);
#endif
// AfxMessageBox("數(shù)據(jù)庫(kù)字段訪問(wèn)錯(cuò)誤!");
}

BOOL CBBRstValues::GetValText(CString &strText, CString &strFieldName)
{
_bstr_t varChunk;
_bstr_t varNotes;
long lngTotalsize,
       lngOffSet = 0,
       lngChunkSize = 100;
_variant_t vFieldName = _variant_t(strFieldName);
lngTotalsize = (*m_prsThis)->Fields->Item[vFieldName]->ActualSize/2;
if (lngTotalsize <= 0)
  return FALSE;

try
{
  while (lngOffSet < lngTotalsize)
  {
   varChunk = (*m_prsThis)->Fields->Item[vFieldName]->GetChunk(lngChunkSize);
   varNotes = varNotes + varChunk;
   lngOffSet = lngOffSet + lngChunkSize;
  }
  strText=(char*)varNotes;
}
catch(_com_error)
{
  ReportError();
  return FALSE;
}
catch(...)
{

#ifdef _DEBUG
  AfxMessageBox("獲取Text字段未知錯(cuò)誤");
#endif
  return FALSE;
}

return TRUE;
}



// 上面代碼,還有沒(méi)有完善的地方,更完善的代碼,在以后會(huì)發(fā)表,現(xiàn)在我已經(jīng)做成了一個(gè)DLL,并而還有一些示例文件,需要DLL和示例文件的,請(qǐng)與我聯(lián)系。EMail: bozi@china.com