大家好,前段时间本菜鸟发表了一篇用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 ; }

|