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