一个功能增强型用ADO访问数据库的类

类别:VC语言 点击:0 评论:0 推荐:

         大家好,前段时间本菜鸟发表了一篇用ADO访问数据库文章,得到许多VC高手的指点,我看了后,感触颇深,对原来的类继续完善,使用起来更加好用,这个类或许还存在

一些不足的地方,但愿VC高手不吝赐教.下面给出类的头文件,实现文件

-------头文件:-------------------------------------------------------------------

#ifndef _ADOEX_H_
#define _ADOEX_H_

#include "stdafx.h"


/*  注 stdafx.h 里要有下面两行          */
/*  #include <comdef.h>                 */  
/*  #import "c:\program files\common files\system\ado\msado15.dll" no_namespace  rename("EOF","adoEOF")  */

/*  AfxOleInit() ;      ADO 初始化  */

#define MAX_FIELD_NUM 500        /*一个表里最大的字段数*/


class CAdoEx 
{
public:
 CAdoEx();
 virtual ~CAdoEx();

 /*打开 Ado 数据库*/
 BOOL OpenAdo(LPCTSTR lpDSN ,LPCTSTR lpTable,LPCTSTR lpUID ,LPCTSTR lpPWD); 
   
     /*------------------------------------------*/    
     /*     ADO 通用查询函数                                          */ 
     /*     调用参数: 正确的SQL 查询语句.                             */
     /*     可以对一个表查询,也可以对多个表查询                       */
     /*     返回一个纪录集                                            */
     /*     特别强调可以调用存储过程,调用方法为: ProcedureName Param1,param2  */
     /*     例如:调用的字符串为  "TestAdo 'luoshizhen1','1999-05-06'"
     /*     如果成功返回一个非空的纪录集                              */
     /*     如果失败则返回一个NULL的纪录集                            */
   _RecordsetPtr Query(LPCTSTR lpQuery);
   /*--------------------------------------------*/
  
 /*--------------------------------------------*/
 /*关闭数据库                                  */
 BOOL CloseAdo();  
 /*--------------------------------------------*/
   
 /*--------------------------------------------*/
    /*     ADO 通用SQL语句执行函数                                      */ 
    /*     调用参数: 正确的SQL 查询语句.                                */
    /*     可以对一个表插入 修改 删除 操作                              */
    /*     可以调用存储过程,调用方法为: ProcedureName Param1,param2     */
    /*     例如:调用的字符串为  "TestAdo 'luoshizhen1','1999-05-06'"     */
    /*     如果成功返回真                                               */
    /*     如果失败返回假                                               */
    BOOL Execute(LPCTSTR lpExcute);
 /*--------------------------------------------*/
public:
   /*该函数对绑定的表进行插入一条纪录,调用方法:              */
   /*1  先调用OpenAdo() 成功                                 */
   /*2  设置该类的成员变量 m_sFields --绑定表的字段总数      */
      /*3  设置成员变量数组 m_sFieldName ,m_sFieldNumeric       */
   /*   m_sFieldPrimary                                      */
   /*   最后把新纪录填充到 m_sFieldValue 数组调用AddReocrd() */
   BOOL AddRecord();

     /*该函数对绑定的表进行插入一条纪录,调用方法:              */
   /*   如果设置过 成员变量m_sFields,m_sFieldName            */
   /*   m_sFieldPrimary,m_sFieldNumeric                      */
   /*   把要修改的数据填充到 m_sFieldValue 数组,调用UpdateReocrd() */
    BOOL UpdateRecord();
 
   /*填充m_sFieldValue 数组,然后调用该函数即可                */
   BOOL DeleteRecord();
  
   /*调用参数 Where后面的条件即可                             */
   /*如果有符合条件的纪录则返回 TRUE                          */
   /*没有符合条件的纪录或则发生异常都返回 FALSE               */
   BOOL SelectMatchRecord(CString& sWhere);

      /*移动到符合条件的纪录的下一个纪录                         */
   /*移动成功返回 TRUE ,到达纪录尾则返回 FALSE                */
      BOOL SelectNextRecord();

   int m_nFields  ;                       /* 绑定表的字段总数   */
   CString m_sFieldName[MAX_FIELD_NUM] ;  /*字段名字数组        */
   CString m_sFieldValue[MAX_FIELD_NUM] ; /*字段数值数组        */
   BOOL m_bFieldNumeric[MAX_FIELD_NUM] ;  /*该字段是否为数值类型*/
   BOOL m_bFieldPrimary[MAX_FIELD_NUM] ;  /*该字段是否为主键    */

protected:
  BOOL GetFieldName();
  _RecordsetPtr retRecordsetPtr;
  _RecordsetPtr m_pFindRecord;
   _ConnectionPtr m_pConnection;
     CString ReplaceString(CString& sText);
  CString m_sTable ;                      /* 要绑定表的名字*/
   char lpBuff[500];
  HRESULT hResult;
   BOOL m_bOpen;               
};

#endif

------- 实现文件:-------------------------------------------------------------------


/*   说明:  这是一个 Ado 类,可以实现用ADO对数据库操作     */
/*   1. 连接数据库                                        */
/*   2. 查询数据库的一个或关联表                          */
/*   3. 执行SQL 语句插入 修改 删除 操作                   */
/*   4. 关闭数据库                                        */

#include "stdafx.h"
#include "AdoEx.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

CAdoEx::CAdoEx()
{
   m_bOpen = FALSE ;
  
   /*初始化连接的实例*/
   m_pConnection.CreateInstance(_uuidof(Connection)) ;
   m_pFindRecord.CreateInstance(_uuidof(Recordset)) ;

   m_nFields = 0 ;
}

CAdoEx::~CAdoEx()
{

  if(retRecordsetPtr !=NULL)
   retRecordsetPtr->Close() ;
  retRecordsetPtr = NULL ;

  CloseAdo() ;

  m_bOpen = FALSE ;
}
/*打开 Ado 数据库*/
BOOL CAdoEx::OpenAdo(LPCTSTR lpDSN,LPCTSTR lpTable,LPCTSTR lpUID ,LPCTSTR lpPWD )
{
 BOOL bRet = FALSE ;
   
 if(m_bOpen) return TRUE ;

 try
 {
       hResult = m_pConnection->Open(lpDSN,lpUID,lpPWD,0)  ;
      
       if (SUCCEEDED(hResult))
    {
         TRACE0("Open ADO Database  Succeeded !\n") ;
         m_bOpen = TRUE ;
      bRet    = TRUE ;
   m_sTable = lpTable ;
    }
    else
    {
      m_bOpen = FALSE ;
         bRet    = FALSE ;
    }
 } /*end of try*/
 catch(_com_error e )
 {
  memset(lpBuff,0x00,500) ;
  sprintf(lpBuff,"打开数据库时发生异常 \n:%s",e.ErrorMessage());
  AfxMessageBox(lpBuff) ;
 }

 return bRet ;
}

/*     ADO 通用查询函数                                          */ 
/*     调用参数: 正确的SQL 查询语句.                             */
/*     可以对一个表查询,也可以对多个表查询                       */
/*     返回一个纪录集                                            */
/*     可以调用存储过程,调用方法为: ProcedureName Param1,param2  */
/*     例如:调用的字符串为  "TestAdo 'luoshizhen1','1999-05-06'"
/*     如果成功返回一个非空的纪录集                              */
/*     如果失败则返回一个NULL的纪录集                            */
_RecordsetPtr CAdoEx::Query(LPCTSTR lpQuery)
{
  retRecordsetPtr = NULL ;
  _variant_t vRecsAffected ;

  if(!m_bOpen) return NULL ;

  try
  {
    retRecordsetPtr = m_pConnection->Execute(lpQuery,
                                     &vRecsAffected,
                              adOptionUnspecified) ;
  }
  catch(_com_error e)
  {
  memset(lpBuff,0x00,500) ;
  sprintf(lpBuff,"查询数据库表时发生异常 \n:%s",e.ErrorMessage());
  AfxMessageBox(lpBuff) ;
  }

   return retRecordsetPtr ;
}

/*     ADO 通用SQL语句执行函数                                      */ 
/*     调用参数: 正确的SQL 查询语句.                                */
/*     可以对一个表插入 修改 删除 操作                              */
/*     可以调用存储过程,调用方法为: ProcedureName Param1,param2     */
/*     例如:调用的字符串为  "TestAdo 'luoshizhen1','1999-05-06'"     */
/*     如果成功返回真                                               */
/*     如果失败返回假                                               */

BOOL CAdoEx::Execute(LPCTSTR lpExcute)
{
  BOOL  bRet  = FALSE ;
  _variant_t vRecsAffected ;

  if(!m_bOpen) return FALSE ;

  try
  {
     m_pConnection->Execute(lpExcute,
                      &vRecsAffected,
                   adOptionUnspecified) ;
    bRet = TRUE ;
  }
  catch(_com_error e)
  {
     bRet = FALSE ;
  memset(lpBuff,0x00,500) ;
  sprintf(lpBuff,"更改数据库表时发生异常 \n:%s",e.ErrorMessage());
  AfxMessageBox(lpBuff) ;
  }

   return bRet  ;
}

BOOL CAdoEx::CloseAdo()
{
    if (m_bOpen)
 {
  m_pConnection->Close() ;
  TRACE0("Close ADO Connection !\n") ;
 }

 return TRUE ;
}

/*删除绑定表的一条纪录*/
/*填充m_sFieldValue 数组,然后调用该函数即可                */
BOOL CAdoEx::DeleteRecord()
{
 CString lpDelete,Temp ;
 _variant_t RecordAffect ;
   
 if (m_sTable=="")
 {
  AfxMessageBox("表名为空,删除失败!") ;
  return FALSE ;
 }
 if (m_sTable==0)
 {
  AfxMessageBox("绑定表的字段总数为0,删除失败!") ;
  return FALSE ;
 }
 if(!m_bOpen)
 {
  AfxMessageBox("还没有连接数据库,删除失败!") ;
  return FALSE ;
 }
  lpDelete.Format("Delete From %s Where ",m_sTable) ;
    
 int ff = 0 ;
    for(int i = 0 ;i<m_nFields;i++)
 {
  if(m_bFieldPrimary[i])
  {
           if(ff > 0)
      lpDelete +=" AND " ;
            ff ++ ;

   if(m_bFieldNumeric[i])
    Temp.Format("%s=%s",m_sFieldName[i],m_sFieldValue[i]) ;
   else
    Temp.Format("%s=%s",m_sFieldName[i],ReplaceString(m_sFieldValue[i])) ;

            lpDelete += Temp ;
  }
 }

 /*进行删除*/
 try
 {
  m_pConnection->Execute((LPCTSTR)lpDelete,
                      &RecordAffect,
          adOptionUnspecified) ;
 }
    catch (_com_error e)
 {
  memset(lpBuff,0x00,500) ;
  sprintf(lpBuff,"删除绑定表时发生异常 \n:%s",e.ErrorMessage());
  AfxMessageBox(lpBuff) ;
  return FALSE ;
  }

 return TRUE ;
}

CString CAdoEx::ReplaceString(CString& sText)
{
   CString sRet ;
   CString cChar ;
   for (int i = 0 ;i<sText.GetLength();i++)
   {
      cChar = sText.Mid(i,1) ;
   if(cChar=="'")
    cChar="''" ;
   sRet += cChar ;
   }

   return CString("'" + sRet +"'") ;
}

/*向绑定的表增加一条纪录*/
/*该函数对绑定的表进行插入一条纪录,调用方法:              */
/*1  先调用OpenAdo() 成功                                 */
/*2  设置该类的成员变量 m_sFields --绑定表的字段总数      */
/*3  设置成员变量数组 m_sFieldName ,m_sFieldNumeric       */
/*   m_sFieldPrimary                                      */
/*   最后把新纪录填充到 m_sFieldValue 数组调用AddReocrd() */
BOOL CAdoEx::AddRecord()
{
    CString lpInsert ,sTemp ;
    _variant_t RecordAffect ;

    if(!m_bOpen)
 {
  ::MessageBox(NULL,"还没有连接数据库!\n插入失败!","提示",MB_ICONEXCLAMATION|MB_OK) ;
  return FALSE ;
 }
 if(m_nFields == 0)
 {
  ::MessageBox(NULL,"绑定表的字段总数没有设置!\n插入失败!","提示",MB_ICONEXCLAMATION|MB_OK) ;
  return FALSE ;
 }
  
 lpInsert.Format("Insert Into %s(",m_sTable) ;

 int ff = 0 ;
 for(int i=0 ;i < m_nFields ;i++)
 {
    if(ff>0)
          lpInsert += "," ;
    ff ++ ;
       lpInsert += m_sFieldName[i] ;      
 }
   
 lpInsert +=") values(" ;
 ff = 0 ;
 for(i= 0 ;i<m_nFields ;i++)
 {
  if(ff>0)
   lpInsert += "," ;
   ff++ ;
   if(m_bFieldNumeric[i])
      sTemp.Format("%s",m_sFieldValue[i]) ;
   else
          sTemp.Format("%s",ReplaceString(m_sFieldValue[i])) ;
   lpInsert += sTemp ;
 }
    lpInsert +=")" ;

 /*向绑定的表插入一条纪录*/
 try
 {
         m_pConnection->Execute((LPCTSTR)lpInsert,
                       &RecordAffect,
        adOptionUnspecified ) ;
 }
    catch(_com_error e)
 {
  memset(lpBuff,0x00,500) ;
  sprintf(lpBuff,"向绑定的表插入一条纪录时发生异常! 插入失败 \n:%s",e.ErrorMessage());
  AfxMessageBox(lpBuff) ;
  return FALSE ;
 }

 return TRUE ;
}

/*更新绑定的表一条纪录*/
BOOL CAdoEx::UpdateRecord()
{
   CString lpUpdate,sTemp ;
   _variant_t RecordAffect ;

   if(!m_bOpen)
   {
    ::MessageBox(NULL,"还没有连接数据库,修改失败!","提示",MB_ICONEXCLAMATION|MB_OK) ;
    return FALSE ;
   }
   if(m_nFields == 0)
   {
    ::MessageBox(NULL,"没有设定绑定表的字段总数,修改失败!","提示",MB_ICONEXCLAMATION|MB_OK) ;
    return FALSE ;
   }

   lpUpdate.Format("Update %s Set ",m_sTable) ;
   int ff= 0 ;
   for(int i=0 ;i<m_nFields;i++)
   {
      if(!m_bFieldPrimary[i])
   {
     if(ff>0)
       lpUpdate += "," ;
     ff++ ;
        if(m_bFieldNumeric[i])
      sTemp.Format("%s=%s",m_sFieldName[i],m_sFieldValue[i]) ;
     else
     sTemp.Format("%s=%s",m_sFieldName[i],ReplaceString(m_sFieldValue[i])) ;
        lpUpdate += sTemp ;
   }
   }
  
   lpUpdate +=" Where " ;
   ff = 0 ;
   for( i=0 ;i<m_nFields ;i++)
   {
    if(m_bFieldPrimary[i])
    {
         if (ff>0)
    lpUpdate += " AND " ;
   ff++ ;
   if(m_bFieldNumeric[i])
    sTemp.Format("%s=%s",m_sFieldName[i],m_sFieldValue[i]) ;
   else
    sTemp.Format("%s=%s",m_sFieldName[i],ReplaceString(m_sFieldValue[i])) ;
         lpUpdate +=sTemp ;
    }
   }

   AfxMessageBox(lpUpdate) ;
  
   /*进行更新绑定表的一条纪录*/
   try
   {
         m_pConnection->Execute((LPCTSTR)lpUpdate,
                        &RecordAffect,
         adOptionUnspecified) ;
   }
   catch(_com_error e)
   {
   memset(lpBuff,0x00,500) ;
  sprintf(lpBuff,"更新定的表的一条纪录时发生异常! 更新失败 \n:%s",e.ErrorMessage());
  AfxMessageBox(lpBuff) ;
  return FALSE ;
   }

   return TRUE ;
}

/*查找绑定表符合条件的纪录                  */
/*如果查询到纪录时,返回真                   */
/*查询没有出错,但是没有符合条件的纪录,返回假*/
/*进行查询时出现异常,返回假                 */
BOOL CAdoEx::SelectMatchRecord(CString &sWhere)
{
    CString lpSelect , sTemp ;
    _variant_t RecordAffect  ; 
    _variant_t FindValue ;

 if(!m_bOpen)
 {
  ::MessageBox(NULL,"还没有连接数据库,查找失败!","提示",MB_ICONEXCLAMATION|MB_OK) ;
  return FALSE ;
 }
    if(m_nFields==0)
 {
        ::MessageBox(NULL,"没有指定绑定表字段的总数,查找失败!","提示",MB_ICONEXCLAMATION|MB_OK) ;
  return FALSE ;
 }

    if(sWhere=="")
       lpSelect.Format("Select * From %s",m_sTable) ;
 else
    lpSelect.Format("Select * From %s Where %s",m_sTable,sWhere) ;

 AfxMessageBox(lpSelect) ;
 /*进行查找纪录*/
 try
 {
        m_pFindRecord = m_pConnection->Execute((LPCTSTR)lpSelect,
                      &RecordAffect ,
          adOptionUnspecified ) ;
  if(!m_pFindRecord->GetadoEOF())
  {
            for(int i =0 ;i<m_nFields;i++)
   {
    FindValue = m_pFindRecord->GetCollect(_variant_t(m_sFieldName[i])) ;
    if(FindValue.vt != VT_NULL)
                  m_sFieldValue[i] = (char*)_bstr_t(FindValue) ;
    else
      m_sFieldValue[i] = "" ;
   }
   return TRUE ;
  }
  else  /*纪录集没有数据*/
   return FALSE ;  
 }
    catch(_com_error e)
 {
   memset(lpBuff,0x00,500) ;
  sprintf(lpBuff,"进行查找绑定表的一条纪录时发生异常! 进行查找失败 \n:%s",e.ErrorMessage());
  AfxMessageBox(lpBuff) ;
  return FALSE ;
 }
}

/*查找下一个纪录,这函数必须调用SelectMatchRecord()函数之后调用 */
/* 返回真时,查找到一个符合条件的纪录                           */
/* 返回假时,往往是纪录尾部了                                   */
BOOL CAdoEx::SelectNextRecord()
{
 HRESULT hMoveNext ;
 _variant_t NextValue ;

    hMoveNext = m_pFindRecord->MoveNext() ;
 if(SUCCEEDED(hMoveNext))
 {
  if(!m_pFindRecord->GetadoEOF())
  {
    for(int i=0 ; i<m_nFields ; i++)
    {
            NextValue = m_pFindRecord->GetCollect(_variant_t(m_sFieldName[i]))  ;
      if(NextValue.vt != VT_NULL)
          m_sFieldValue[i] =(char*)_bstr_t(NextValue)  ;
     else
             m_sFieldValue[i] = "" ;
    }
          return TRUE ;
  }
  else
          return FALSE ;
 }
 else
  return FALSE ;

}

/*表的所有字段*/
BOOL CAdoEx::GetFieldName()
{
   _variant_t RecordAffect ;
   LPSTR lpSelect  ;
   _RecordsetPtr m_Recordset ;
   FieldPtr m_FieldPtr ;

   if(!m_bOpen)
    return FALSE ;
 
   lpSelect = new char[100] ;
   memset((char*)lpSelect,0x00,100) ;
   sprintf(lpSelect,"Select * From %s",m_sTable) ;

   m_Recordset = m_pConnection->Execute(lpSelect,
                                      &RecordAffect,
           adOptionUnspecified) ;
   m_FieldPtr = m_Recordset->GetFields() ;

   delete lpSelect ;

   return TRUE ;
}

 

 

本文地址:http://com.8s8s.com/it/it3027.htm