封裝ADO訪問資料庫的兩個類 (轉)

worldblog發表於2007-12-08
封裝ADO訪問資料庫的兩個類 (轉)[@more@]

 


 


 


 


 


 


  對於初學者,使用ADO訪問的時候,涉及到各種資料型別轉換,可能有一些難度,我試圖封裝了ADO訪問資料庫,使其更方便的用現有的VC的資料型別,更加方便的使用ADO運算元據庫。
下面分別提供兩個封裝ADO資料庫訪問的類,一個是資料庫的連線類,一個是資料庫欄位訪問的類。


  在連線類中,大家可以看到,連線類中並沒有Recordset的成員變數,因為這樣的,在整個資料庫應用中,資料庫的連線一般一個就夠了,而同時開啟的Reocordset則可能不只一個,所以,如果兩個在同一個類裡,那麼,如果要同時開啟兩個記錄集,需要建立類的兩個例項,就是需要同時開啟兩個資料庫連線,如果對於連線的是同一個資料庫,同時開啟兩個連線的話,意味著資源的不必要的浪費。


  資料庫欄位訪問類,簡化了,獲取資料庫欄位內容的操作,避免了資料型別轉換的麻煩。


  兩個類都對錯誤處理進行了較多的考慮,在訪問資料庫中,如果沒有錯誤處理,其害處是顯而易見的。


 



#ifndef _BBADOCONNECT_H
#define _BBADOCONNECT_H


//
// ADO訪問資料庫類
// 環境:需要MSADO15.DLL
// 作者:鄧振波
// 2001.4.20
// E:
//主頁:/">seesi.51.net


// 說明:封裝了ADO使用的操作和ADO訪問資料庫錯誤處理
//  使在VC上方便的使用ADO訪問資料庫
// 包括:ADO連線資料庫、開啟記錄集、、以及
//  事務處理、ADO記錄集內容轉換成C++的常用資料型別(CString、char,long,float等)
//
// 使用:1。定義一個CBBAdoConnection例項:CBBAdoConnection m_adoConn;
//  2。建立連線:m_adoConn.Open(strConnstring);
//  如果需要無條件重新連線的可以,引數bRepen設成TREU
//  3。開啟記錄集:
//
//  _RecordsetPtr* prsThis=NULL;
//  prsThis=new _RecordsetPtr;
//  CString strSQL;
//  strSQL=" * from Table_Name";// 
//  如果記錄集開啟失敗
// 


if(!(m_adoConn.OpenRecordset(strSQL,prsThis)))
//  return FALSE;
//  4。建立記錄集值
//  注意需要用引數構造
//  CBBRstValues rsv(m_adoConn,prsThis);
// 
//  5。獲得的欄位的值
//  rsv.GetValueLong(&m_nDeptID,1L);//獲得第一個欄位的值
//  rsv.GetValueStr(m_strName,"ID");//獲得第一個欄位名為ID的值
//  其它的同理.如果需要獲得中nText型別的欄位值請用
//  GetValText(CString &strText, CString &strFieldName)函式
//  6。記錄集的記錄移動 (*prsThis)->MoveNext()等類似函式
//  7。記錄集不用時候需要釋放其資源
//  1)關閉記錄集
//  2)刪除記錄集指標
//  e.g. (*prsThis)->Close();
//  delete prsThis;
//  prsThis=NULL;
//  否則會造成洩漏
// 
//  注:
//  1。程式必須要初始化COM環境,請在應用類中加入AfxOleInit函式初始化環境,否則ADO的將失敗
//  2。如果需要呼叫過程SQL語句改為“Exec ” + 儲存過程名即可,與執行SQL同樣
//
//  CopyRight seesi,2001
//
//  說明:你可以隨便在的程式中任意使用、修改本程式碼,但請你不要刪除頭的部分說明。如果需要轉載,請註明出處。
// 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); // 設定連線超時
 int SetCommTimeOut(long lTimeOut); // 設定命令執行超時
 BOOL InnectClose(); // 判斷連線是否已經開啟
 int ExecuteSQL(LPCSTR szSQL); // 簡單執行SQL語句,不返回記錄集
 // 開啟資料庫記錄集
 // 引數:
 //  strSQL  記錄集的SQL語句
 //  rs  返回的記錄集_RecordsetPtr物件
 //  sConnString 資料庫的連線字串
 //  如果使用資料庫連線已經開啟,引數沒用
 //  如果資料庫的連線沒有開啟,當給予一個連線字串,將先開啟資料庫連線
 BOOL OpenRecordset(CString strSQL, _RecordsetPtr *rs,CString sConnString="");//開啟資料庫記錄集
 BOOL OpenRecordset(const char *sSQL,_RecordsetPtr* rs,char* sConnString=NULL);


 // 開啟資料庫連線
 // 引數:
 //  strConnString 連線字串
 //  sConnString  連線字串
 //  bReOpen  是否重新開啟,如果為FALSE,,
 //  將先判斷資料庫是否開啟如果沒有開啟則開啟,
 //  如果已經開啟,將不執行任何操作
 //  如果為TRUE,則無條件重新開啟。
 BOOL OpenConnection(CString strConnString ,BOOL bReOpen=FALSE);
 BOOL OpenConnection(char* sConnString,BOOL bReOpen=FALSE); void CloseConnect();// 關閉資料庫連線


 BOOL ExecuteTrans(CStringArray arrStrSQL); // 事務處理,不返回任何記錄集,引數為事務SQL陣列



 _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:
 // 三種構造類的方法
 // 如果無引數構造,請構造後呼叫InitConnectAndRst方法
 // 其他的兩種構造則不需呼叫InitConnectAndRst方法
 CBBRstValues();
 CBBRstValues(_ConnectionPtr* pConn,_RecordsetPtr* pRs);
 CBBRstValues(CBBAdoConnection* pBBadoConn,_RecordsetPtr*


pRs);


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


 // GetValText函式
 // 得到資料庫nText欄位的值
 // 引數:
 //  strText  用來接收返回值(欄位值)
 //  strFieldName 欄位名,該欄位資料型別必須是nText型別
 BOOL GetValText(CString& strText,CString& strFieldName); //得到資料庫nText欄位的值
 
 // GetValueStr函式
 // 得到數字型,日期型和字元型欄位值函式
 // 引數:
 //  cVal  用來接收返回值(欄位值)的字串指標,要求要開闢足夠的記憶體單元
 //   或者足夠容納欄位內容的字元陣列。
 //  vIndex  資料庫欄位的名字或者,變體型,一般不直接用這個引數,
 //  應該用同形式的多型函式的引數呼叫
 //  資料庫欄位的資料型別可以是數字型,日期型和字元型
 //  nFieldLen  需要返回的資料的字串的長度,如果為-1,則返回整個欄位值
 //  lpszFieldName 欄位名,資料庫欄位的資料型別可以是數字型,日期型和字元型
 //  nFieldIndex  在SQL語句中欄位的索引序號資料庫欄位的資料型別可以是數字型,日期型和字元型


 // GetValueLong函式
 // 得到數字型,日期型和字元型欄位值函式
 // 引數:
 //  lVal  用來接收返回值(欄位值)
 //  vIndex  資料庫欄位的名字或者索引,變體型,一般不直接用這個引數,
 //  應該用同形式的多型函式的引數呼叫
 //  資料庫欄位的資料型別要求是數字型(int,long)
 //  lpszFieldName 欄位名,資料庫欄位的資料型別可以是數字型,日期型和字元型
 //  nFieldIndex  在SQL語句中欄位的索引序號資料庫欄位的資料型別可以是數字型,日期型和字元型


 // GetValueFlaot函式
 // 得到數字型,日期型和字元型欄位值函式
 // 引數:
 //  fVal  用來接收返回值(欄位值)
 //  vIndex  資料庫欄位的名字或者索引,變體型,一般不直接用這個引數,
 //  應該用同形式的多型函式的引數呼叫
 //  資料庫欄位的資料型別要求是字型(int,long,float,貨幣型等)
 //  lpszFieldName 欄位名,資料庫欄位的資料型別可以是數字型,日期型和字元型
 //  nFieldIndex  在SQL語句中欄位的索引序號資料庫欄位的資料型別可以是數字型,日期型和字元型


 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()
{
 // 關比連線
 CloseConnect();
}


BOOL CBBAdoConnection::OpenConnection(char *sConnString,BOOL bReOpen /*=FALSE*/)
{
 
 // 不需重新開啟
 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 _DE // 時顯示相應的錯誤資訊
  MessageBox(NULL,"資料庫連線未處理的異常!","連線失敗",MB_OK|MB_ICONINFORMATION);
  #else
  MessageBox(NULL,"連線資料失敗,請檢查和資料庫設定是否正確","連線失敗",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;
  }
  // 嘗試連線資料庫
  else
  {
  //
  // if(!OpenConnection(m_szConnString))
  // return FALSE;
  // MessageBox(NULL,"資料庫連線已經斷開,請重新連線!","連線問題",MB_OK|MB_ICONINFORMATION); 
  }


  return FALSE;
  } 
  // rs=new _RecordsetPtr;
  HRESULT hr;
  hr=rs->CreateInstance(__uuidof(Recordset));
  if(FAILED(hr))
  { 
  return FALSE;// 建立例項失敗
  } 
  hr=(*rs)->Open(sSQL,m_pConn->GetInterfacePtr(),
  adOpenStatic, adLockBatchOptimistic, -1);
  if(FAILED(hr))
  { 
  return FALSE;// 開啟連線失敗
  } 
  return TRUE;// 成功返回
 }
 catch(_com_error)
 {
 
  // AfxMessageBox(ce->Description());
  ReportError(ErrFromOpenRecordset);
  return FALSE;
 }
 catch(...)
 {
  MessageBox(NULL,"資料庫記錄開啟失敗!","記錄失敗",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("關閉資料庫連線未知錯誤!");
 }
}


 


 


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) // 開始事務處理,不返回任何記錄集,引數為事務SQL陣列
{
 
 (*m_pConn)->BeginTrans();


 try
 {
  _RecordsetPtr* prsThis;
  for(int i=0;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;
 }
}


 



// 執行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;
}


// 返回是否處在連線狀態
BOOL CBBAdoConnection::IsConnectClose()
{


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


// 設定連線超時
int CBBAdoConnection::SetConnTimeOut(long lTimeOut)
{
 return (*m_pConn)->put_ConnectionTimeout(lTimeOut);
}


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


// 報告錯誤
void CBBAdoConnection::ReportError(int nERRORfrom)
{
 switch(nERRORfrom)
 {
 case ErrFormOpenConnsction:
  #ifdef _DEBUG  // 除錯試時顯示相應的錯誤資訊
  try
  {
  for(long l=0;lErrors->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,"資料庫連線未知錯誤,無法捕捉具體錯誤資訊!","錯誤",MB_ICONINFORMATION);
  }
  #else
  MessageBox(NULL,"連線資料失敗,請檢查網路和資料庫設定是否正確","連線失敗",MB_OK|MB_ICONINFORMATION);
  #endif
  break;
 case ErrFromOpenRecordset:
  #ifdef _DEBUG
  try
  { 
  for(long i=0;iErrors->Count;i++)
  {
  ErrorPtr pErr;
  pErr=(*m_pConn)->Errors->GetItem(i);
  AfxMessageBox(pErr->Description);
  }
  }
  catch(...)
  {
  MessageBox(NULL,"資料庫連線未知錯誤,無法捕捉具體錯誤資訊!","錯誤",MB_ICONINFORMATION);
  }
  #else
  MessageBox(NULL,"開啟資料庫失敗,請檢查網路,並嘗試重新連線資料庫!","記錄失敗",MB_OK|MB_ICONINFORMATION);
  #endif
  break;
 case ErrFormCloseConnection:
  #ifdef _DEBUG  // 除錯時顯示相應的錯誤資訊
  try
  {
  for(long l=0;lErrors->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,"資料庫連線未知錯誤,無法捕捉具體錯誤資訊!","錯誤",MB_ICONINFORMATION);
  }


  #else
  ;// MessageBox(NULL,"關閉資料庫連線異常","關閉異常",MB_OK|MB_ICONINFORMATION);
  #endif
  break;
 case ErrFormTanslation:
  #if def _DEBUG
  try
  {
  for(long i=0;iErrors->Count;i++)
  {
  ErrorPtr pErr;
  pErr=(*m_pConn)->Errors->GetItem(i);
  AfxMessageBox(pErr->Description);
  }
  }
  catch(...)
  {
  MessageBox(NULL,"資料庫連線未知錯誤,無法捕捉具體錯誤資訊!","錯誤",MB_ICONINFORMATION);
  }
  #else
  MessageBox(NULL,"資料庫執行任務失敗,請檢查資料庫。","任務失敗",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("記錄集未開啟!");
#else
  MessageBox(NULL,"無法讀取資料庫資料,可能資料庫連線已經斷開,請重新連線、然後重試。","連線問題",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("資料庫欄位訪問未知錯誤!請檢查資料庫是否改動。",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;
 
 // 檢查是陣列
 // VERIFY(sizeof(cVal)<1);
 memset(cVal,0,sizeof(cVal));
 try
 {
  if((*m_prsThis)==NULL||(*m_prsThis)->State==adStateClosed)
  {
#ifdef _DEBUG
  AfxMessageBox("記錄集未開啟!");
#else
  MessageBox(NULL,"無法讀取資料庫資料,可能資料庫連線已經斷開,請重新連線、然後重試。","連線問題",MB_ICONINFORMATION);
#endif
  return FALSE;
  }


  if((*m_prsThis)->adoEOF)
  {
  cVal[0]=';
  return FALSE;
  }
  value = (*m_prsThis)->GetCollect(vIndex);
 }
 catch(_com_error)
 {
  ReportError();
  // AfxMessageBox("資料庫欄位訪問錯誤!");
  return FALSE;
 }
 catch(...)
 {
  AfxMessageBox("資料庫欄位訪問未知錯誤!請檢查資料庫是否改動。",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]=';
  } 
  }
  delete c;
  c=NULL;
  break;
  default:
#ifdef _DEBUG
  AfxMessageBox("未處理的欄位資料型別,請處理!");
#else
  break;
#endif
  break;
  }
 }


 else
 {
  cVal[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("記錄集未開啟!");
#else
  MessageBox(NULL,"無法讀取資料庫資料,可能資料庫連線已經斷開,請重新連線、然後重試。","連線問題",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("資料庫欄位訪問未知錯誤!請檢查連線資料庫結構是否已經更改。",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;lErrors->Count;l++)
  {
  ErrorPtr pErr;
  pErr=(*m_pConn)->Errors->GetItem(l);
  AfxMessageBox(pErr->Description);
  } 
 }
 catch(...)
 {
  AfxMessageBox("欄位錯誤物件訪問錯誤,請檢查書寫是否正確。");
 }
#else
 MessageBox(NULL,"欄位訪問發生錯誤,請確認資料庫結構沒有改動。","欄位訪問",MB_ICONINFORMATION);
#endif
 // AfxMessageBox("資料庫欄位訪問錯誤!");
}


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欄位未知錯誤");
#endif
  return FALSE;
 }


 return TRUE;
}


 


// 上面程式碼,還有沒有完善的地方,更完善的程式碼,在以後會發表,現在我已經做成了一個DLL,並而還有一些示例檔案,需要DLL和示例檔案的,請與我聯絡。:


 


更多文章在我的個人主頁:


 


 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989755/,如需轉載,請註明出處,否則將追究法律責任。

相關文章