N多年没有碰过数据库了,最近一个项目要用到数据库,采用SQL 2008,今天重新开始学习数据库,感觉还是挺吃力的,半路出家,小公司,做的东西太广,这里搞一下,那里搞一下,没有搞精通的,都懂些皮毛,呵呵!
在数据库中,我采用ADO连接数据库,使用ADO操作数据的方法如下:
1) 初始化COM库,引入ADO库定义文件;
2) 使用Connection对象连接数据库;
3) 通过建立好的连接,利用Recordset对象取的结果记录集进行查询处理,也可以通过Conection, Command对象执行SQL命令;
4) 关闭连接释放对象;
(一) COM库的初始化,ADO接口简介
// 初始化COM,创建ADO连接等操作
AfxOleInit();
m_pConnection.CreateInstance(__uuidof(Connection));
ADO库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。
_ConnectionPtr接口返回一个记录集或一个空指针。
_CommandPtr接口返回一个记录集:
它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。
在使用_CommandPtr接口时,你可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。如果只执行一次或几次数据访问操作,后者是比较好的选择。
_RecordsetPtr是一个记录集对象:使用_RecordsetPtr执行存储过程和SQL语句。
_ConnectionPtr m_pConnection;
(二) 用#import指令引入ADO类型库
// 加入ADO支持库,
#import "C:\program files\common files\system\ado\msado15.dll" \
no_namespace \
rename ("EOF","adoEOF")
(三)连接数据库
Provider=MSDASQL.1和Provider=SQLOLEDB.1
数据库驱动模型还有ODBC的,SQLOLEDB这个是 OLE
/ OLE --ADO( ADO.NET) \
数据库接口 程序
\ odbc /
MSDASQL是采用ODBC,SQLOLEDB是采用ADO连接数据库;
用法如下:
// 初始化COM,创建ADO连接等操作
AfxOleInit();
m_pConnection.CreateInstance(__uuidof(Connection));
// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息,
//
try
{
// 打开本地数据库
m_pConnection->Open("Provider=MSDASQL.1;Persist Security Info=False; Data Source=数据源","","",adModeUnknown);
}
catch(_com_error e)//抛出可能发生的异常
{
AfxMessageBox("数据库连接失败,确认数据库配置正确!");
return FALSE;
}
而SQLOLEDB的用法如下:
try
{
// m_pConnection.CreateInstance("ADODB.Connection");
_bstr_t strConnect="Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=TEST;Data Source=ip地址,端口号";
m_pConnection->Open(strConnect,"","",adModeUnknown);
}
catch(_com_errore)
{
AfxMessageBox(e.Description());
}
----- ADO连接SQL Server的数据库连接字符串模板 ----------
身份验证模式为:"sql server和windows"
Provider=SQLOLEDB.1;Persist Security Info=True; User ID=用户名;Password=密码;Initial Catalog=数据库名;Data Source=SQL服务器名
身份验证模式为:"仅windows"
Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=数据库名;Data Source=SQL服务器名
Open 函数原型如下:
HRESULT Connection15::Open (_bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options )
ConnectionString 为连接字串,
UserID 是用户名,
Password 是登陆密码,
Options 是连接选项,用于指定Connection对象对数据的更新许可权,
Options可以是如下几个常量:
adModeUnknown: 缺省。当前的许可权未设置
adModeRead: 只读
adModeWrite: 只写
adModeReadWrite: 可以读写
adModeShareDenyRead: 阻止其它Connection对象以读权限打开连接
adModeShareDenyWrite: 阻止其它Connection对象以写权限打开连接
adModeShareExclusive: 阻止其它Connection对象打开连接
adModeShareDenyNone: 允许其它程序或对象以任何权限建立连接
(四)执行SQL命令并取得结果记录集
为了取得结果记录集,定义一个指向Recordset对象的指针:
_RecordsetPtr m_pRecordset;
并为其创建Recordset对象的实例:
m_pRecordset.CreateInstance("ADODB.Recordset");
4.1)通过Connection对象的Execute方法执行SQL命令
Bool ExecuteSQL(_bstr_tbstrSQL)
{
try
{
m_pConnection->Execute(bstrSQL,NULL,adCmdText);
return true;
}
catch(_com_errore)
{
e.Description();
return false;
}
}
Execute方法的原型如下所示:
_RecordsetPtr Connection15::Execute (_bstr_t CommandText, VARIANT * RecordsAffected, long Options )
其中
CommandText 是命令字串,通常是SQL命令。
RecordsAffected 是操作完成后所影响的行数,
Options 表示CommandText中内容的类型,Options可以取如下值之一:
adCmdText: 表明CommandText是文本命令
adCmdTable: 表明CommandText是一个表名
adCmdProc: 表明CommandText是一个存储过程
adCmdUnknown: 未知
4.2) 利用 Command对象来执行SQL命令
Bool ExecuteSQL(_bstr_t bstrSQL)
{
_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
m_pCommand->ActiveConnection = m_pConnection; //关键的一句,将建立的连接赋值给它
m_pCommand->CommandText=bstrSQL;
try
{
m_pConnection->Execute(NULL,NULL,adCmdText);
return true;
}
catch(_com_errore)
{
e.Description();
return false;
}
}
m_pCommand->CommandText="SELECT COUNT(*) FROM表";
m_pRecordset=m_pCommand->Execute(NULL,NULL,adCmdText);
_variant_t vCount = m_pRecordset->GetCollect((_variant_t)(long)0); //取得第一个字段的值
(3) 直接用Recordset对象进行查询取得记录集
_RecordsetPtr& GetRecordSet(_bstr_t bstrSQL)
{
try
{
if(m_pConnection==NULL)
OnInitADOConn();
m_pRecordset.CreateInstance(__uuidof(Recordset));
m_pRecordset->Open(bstrSQL,m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
}
catch(_com_errore)
{
e.Description();
}
return m_pRecordset;
}
Open方法的原型是这样的:
HRESULT Recordset15::Open ( const _variant_t & Source, const _variant_t & ActiveConnection, enum CursorTypeEnum CursorType, enum LockTypeEnum LockType, long Options )
其中:
①Source是数据查询字符串
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
enum CursorTypeEnum
{
adOpenUnspecified = -1, //不作特别指定
adOpenForwardOnly = 0, //前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
adOpenKeyset = 1, //采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
adOpenDynamic = 2, //动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
adOpenStatic = 3 //静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
};
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
enum LockTypeEnum
{
adLockUnspecified = -1, //未指定
adLockReadOnly = 1, //只读记录集
adLockPessimistic = 2, //悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
adLockOptimistic = 3, //乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
adLockBatchOptimistic = 4, //乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
};
⑤Options可以是如下几个常量:
adModeUnknown: 缺省。当前的许可权未设置
adModeRead: 只读
adModeWrite: 只写
adModeReadWrite: 可以读写
adModeShareDenyRead: 阻止其它Connection对象以读权限打开连接
adModeShareDenyWrite: 阻止其它Connection对象以写权限打开连接
adModeShareExclusive: 阻止其它Connection对象打开连接
adModeShareDenyNone: 允许其它程序或对象以任何权限建立连接
(4) 记录集的遍历
try
{
if(!m_pRecordset->BOF)//判断指针是否在数据集最后
m_pRecordset->MoveFirst();
else
{//提示错误,无数据
AfxMessageBox("表内数据为空");
return false;
}
// read data from the database table
while(!m_pRecordset->adoEOF)
{
var = m_pRecordset->GetCollect("凭证号码");
m_pRecordset->MoveNext();//移动数据指针
}
}
catch(_com_error *e)//捕获异常
{
AfxMessageBox(e->ErrorMessage());
}
其中:BOF、EOF属性定义如下:
- BOF 指示当前记录位置位于 Recordset对象的第一个记录之前。
- EOF 指示当前记录位置位于 Recordset对象的最后一个记录之后。
返回值
BOF 和 EOF属性返回布尔型值。
说明
使用 BOF 和 EOF属性可确定 Recordset 对象是否包含记录,或者从一个记录移动到另一个记录时是否超出 Recordset对象的限制。
(5)关闭连接
// 关闭记录集
m_pRecordset->Close();
m_pRecordset = NULL;
附:一个数据操作的类,下面的类不是我写的,我是转载别人的。
ADOConn.cpp文件如下:
#include "StdAfx.h"
#include "ADOConn.h"
//功能:构造函数
//strData:数据库的名字
CString CADOConn::GetAppPath()
{
char lpFileName[MAX_PATH];
GetModuleFileName(AfxGetInstanceHandle(),lpFileName,MAX_PATH);
CString strFileName = lpFileName;
int nIndex = strFileName.ReverseFind ('\\');
CString strPath;
if (nIndex > 0)
strPath = strFileName.Left (nIndex);
else
strPath = "";
return strPath;
}
CADOConn::CADOConn(CString strData)
{
CString strValue;
strData.TrimLeft();
strData.TrimRight();
m_strData=_bstr_t(strData);
strValue=strData.Right(3);
if(strValue=="mdb") m_DataType=1;
if(strValue=="xls") m_DataType=2;
}
CADOConn::CADOConn()
{
m_DataType=3;
}
//功能:析构函数
CADOConn::~CADOConn()
{
}
//功能:初始化数据库连接
void CADOConn::OnInitCADOConn()
{
// 初始化OLE/COM库环境
::CoInitialize(NULL);
try
{
//初始化指针
m_pConnection=NULL;
//初始化指针
m_pRecordset=NULL;
// 创建Connection对象
m_pConnection.CreateInstance("ADODB.Connection");
// 设置连接字符串,必须是BSTR型或者_bstr_t类型
_bstr_t strConnect;
switch(m_DataType)
{
case 1://ACCESS
strConnect=_bstr_t("Provider=Microsoft.Jet.OLEDB.4.0;");
strConnect=strConnect+_bstr_t("Data Source=");
strConnect=strConnect+_bstr_t(GetAppPath())+_bstr_t("\\");
strConnect=strConnect+m_strData;
break;
case 2://EXCEL
strConnect=_bstr_t("Provider=Microsoft.Jet.OLEDB.4.0;");
strConnect=strConnect+_bstr_t("Data Source=");
strConnect=strConnect+_bstr_t(GetAppPath())+_bstr_t("\\");
strConnect=strConnect+m_strData;
strConnect=strConnect+";Extended Properties=Excel 8.0";
break;
case 3://SQLSERVER
strConnect=_bstr_t("Provider=Microsoft.Jet.OLEDB.4.0;");
strConnect=strConnect+_bstr_t("Data Source=D:\\FECG\\");
strConnect=strConnect+";Extended Properties=Excel 8.0";
break;
}
m_pConnection->Open(strConnect,_bstr_t(""),_bstr_t(""),adModeUnknown);
}
// 捕捉异常
catch(_com_error e)
{
// 显示错误信息
AfxMessageBox(e.Description());
}
ASSERT(m_pConnection != NULL);
}
//功能:执行查询
//返回值:字段集的指针
_RecordsetPtr& CADOConn::GetRecordSet(CString strSQL)
{
try
{
// 连接数据库,如果Connection对象为空,则重新连接数据库
if(m_pConnection==NULL)OnInitCADOConn();
strSQL.TrimLeft();
strSQL.TrimRight();
// 创建记录集对象
m_pRecordset.CreateInstance(__uuidof(Recordset));
// 取得表中的记录
m_pRecordset->Open(_bstr_t(strSQL),m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
}
// 捕捉异常
catch(_com_error e)
{
// 显示错误信息
AfxMessageBox(e.Description());
}
ASSERT(m_pRecordset!= NULL);
// 返回记录集
return m_pRecordset;
}
//功能:打开字符集
//返回值:TRUE:成功 FALSE:失败
BOOL CADOConn::Open(CString strSQL)
{
try
{
// 连接数据库,如果Connection对象为空,则重新连接数据库
if(m_pConnection==NULL) OnInitCADOConn();
strSQL.TrimLeft();
strSQL.TrimRight();
// 创建记录集对象
m_pRecordset.CreateInstance(__uuidof(Recordset));
// 取得表中的记录
m_pRecordset->Open(_bstr_t(strSQL),m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
}
// 捕捉异常
catch(_com_error e)
{
// 显示错误信息
AfxMessageBox(e.Description());
return FALSE;
}
// 返回记录集
ASSERT(m_pRecordset!= NULL);
return TRUE;
}
//功能:记录集移向开头
//返回值:TRUE:成功 FALSE:失败
BOOL CADOConn::MoveFirst()
{
if(m_pRecordset==NULL)
return FALSE;
else
{
m_pRecordset->MoveFirst();
return TRUE;
}
}
//功能:记录集向下移动
//返回值:TRUE:成功 FALSE:失败
BOOL CADOConn::MoveNext()
{
if(m_pRecordset==NULL)
return FALSE;
else
{
if (!m_pRecordset->adoEOF)
{
m_pRecordset->MoveNext();
return TRUE;
}
else
return FALSE;
}
}
//功能:取得字段中的字符串
//index:字段集中的索引
//strSum:返回的字符的长度(<=实际:代表全部返回,>实际:左补空格)
CString CADOConn::GetValueString(int index,int strSum)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
CString strValue,strType,str;//strValue:初始返回值 strType:格式化字符串 str:最终返回值
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
str="";
break;
case VT_ERROR:
str="";
break;
case VT_EMPTY:
str="";
break;
default:
str=(LPCSTR)_bstr_t(vValue);
}
strType.Format("%d",strSum);
strType="%"+strType+"s";
strValue.Format(strType,str);
return strValue;
}
//功能:取得字段中的字节型整数
//index:字段集中的索引
byte CADOConn::GetValueByte(int index)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
byte bValue;//数值返回值
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
bValue=0;
break;
case VT_ERROR:
bValue=0;
break;
case VT_EMPTY:
bValue=0;
break;
default:
bValue=vValue.bVal;
}
return bValue;
}
//功能:取得字段中的字节型整数的字符串形式
//index:字段集中的索引
//strSum:返回的字符的长度(<=实际:代表全部返回,>实际:左补空格)
CString CADOConn::GetValueByteStr (int index,int strSum)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
byte bValue;//数值返回值
CString strValue,strType;//strValue:字符串返回值 strType:格式化字符串
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
bValue=0;
break;
case VT_ERROR:
bValue=0;
break;
case VT_EMPTY:
bValue=0;
break;
default:
bValue=vValue.bVal;
}
strType.Format("%d",strSum);
strType="%"+strType+"d";
strValue.Format(strType,bValue);
return strValue;
}
//功能:取得字段中的短整型整数
//index:字段集中的索引
int CADOConn::GetValueInt(int index)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
int iValue;//数值返回值
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
iValue=0;
break;
case VT_ERROR:
iValue=0;
break;
case VT_EMPTY:
iValue=0;
break;
default:
iValue=vValue.iVal;
}
return iValue;
}
//功能:取得字段中的短整型整数的字符串形式
//index:字段集中的索引
//strSum:返回的字符的长度(<=实际:代表全部返回,>实际:左补空格)
CString CADOConn::GetValueIntStr(int index,int strSum)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
int iValue;//数值返回值
CString strValue,strType;//strValue:字符串返回值 strType:格式化字符串
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
iValue=0;
break;
case VT_ERROR:
iValue=0;
break;
case VT_EMPTY:
iValue=0;
break;
default:
iValue=vValue.iVal;
}
strType.Format("%d",strSum);
strType="%"+strType+"d";
strValue.Format(strType,iValue);
return strValue;
}
//功能:取得字段中的双精度浮点数
//index:字段集中的索引
double CADOConn::GetValueDouble(int index)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
double dValue;//数值返回值
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
dValue=0;
break;
case VT_ERROR:
dValue=0;
break;
case VT_EMPTY:
dValue=0;
break;
default:
dValue=vValue.dblVal;
}
return dValue;
}
//功能:取得字段中的双精度浮点数的字符串形式
//index:字段集中的索引
//strLSum(整数部分):返回的整数部分的长度(<=实际:代表全部返回,>实际:左补空格)
//strRSum(小数部分):返回的小数部分的长度(<=实际:代表全部返回,>实际:右补空格)
CString CADOConn::GetValueDoubleStr(int index,int strLSum,int strRSum)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
double dValue;//数值返回值
CString strValue,strType;//strValue:字符串返回值 strType:格式化字符串
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
dValue=0;
break;
case VT_ERROR:
dValue=0;
break;
case VT_EMPTY:
dValue=0;
break;
default:
dValue=vValue.dblVal;
}
strType.Format("%d.%d",strLSum,strRSum);
strType="%"+strType+"f";
strValue.Format(strType,dValue);
return strValue;
}
//功能:取得字段中的单精度浮点数
//index:字段集中的索引
float CADOConn::GetValueFloat(int index)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
float fValue;//数值返回值
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
fValue=0;
break;
case VT_ERROR:
fValue=0;
break;
case VT_EMPTY:
fValue=0;
break;
default:
fValue=vValue.fltVal;
}
return fValue;
}
//功能:取得字段中的单精度浮点数的字符串形式
//index:字段集中的索引
//strLSum(整数部分):返回的整数部分的长度(<=实际:代表全部返回,>实际:左补空格)
//strRSum(小数部分):返回的小数部分的长度(<=实际:代表全部返回,>实际:右补空格)
CString CADOConn::GetValueFloatStr(int index,int strLSum,int strRSum)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
float fValue;//数值返回值
CString strValue,strType;//strValue:字符串返回值 strType:格式化字符串
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
fValue=0;
break;
case VT_ERROR:
fValue=0;
break;
case VT_EMPTY:
fValue=0;
break;
default:
fValue=vValue.fltVal;
}
strType.Format("%d.%d",strLSum,strRSum);
strType="%"+strType+"f";
strValue.Format(strType,fValue);
return strValue;
}
//功能:取得字段中的长整型整数的字符串
//index:字段集中的索引
long CADOConn::GetValueLong(int index)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
long lValue;//数值返回值
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
lValue=0;
break;
case VT_ERROR:
lValue=0;
break;
case VT_EMPTY:
lValue=0;
break;
default:
lValue=vValue.lVal;
}
return lValue;
}
//功能:取得字段中的长整型整数的字符串形式
//index:字段集中的索引
//strSum:返回的字符的长度(<=实际:代表全部返回,>实际:左补空格)
CString CADOConn::GetValueLongStr(int index,int strSum)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
long lValue;//数值返回值
CString strValue,strType;//strValue:字符串返回值 strType:格式化字符串
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
lValue=0;
break;
case VT_ERROR:
lValue=0;
break;
case VT_EMPTY:
lValue=0;
break;
default:
lValue=vValue.lVal;
}
strType.Format("%d",strSum);
strType="%"+strType+"d";
strValue.Format(strType,lValue);
return strValue;
}
//返回时间型值
//数据库中存的格式为字符串(yyyy-mm-dd HH-MM-SS)
CTime CADOConn::GetValueDate(int index)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
CString strValue;//数值返回值
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
strValue="1980-08-08";
break;
case VT_ERROR:
strValue="1980-08-08";
break;
case VT_EMPTY:
strValue="1980-08-08";
break;
default:
strValue=(LPCSTR)_bstr_t(vValue);
break;
}
CString strYear,strMonth,strDay,strHour,strMin,strSec;
strYear=strValue.Mid(0,4);
strMonth=strValue.Mid(5,2);
strDay=strValue.Mid(8,2);
if(strValue.GetLength()>10)
{
strHour=strValue.Mid(11,2);
strMin=strValue.Mid(14,2);
strSec=strValue.Mid(17,2);
}
else
{
strHour="0";
strMin="0";
strSec="0";
}
CTime TValue(atoi(strYear),atoi(strMonth),atoi(strDay),atoi(strHour),atoi(strMin),atoi(strSec));
return TValue;
}
//返回时间型值的字符串
//数据库中存的格式为字符串(yyyy-mm-dd HH-MM-SS)
CString CADOConn::GetValueDateStr(int index,CString strType)
{
_variant_t vValue;//var型返回值
_variant_t vIndex;//索引
CString strValue="";//数值返回值
vIndex.vt=VT_I2;
vIndex.iVal=index;
vValue=m_pRecordset->Fields->GetItem(vIndex)->Value;
switch(vValue.vt)
{
case VT_NULL:
strValue="1980-08-08";
break;
case VT_ERROR:
strValue="1980-08-08";
break;
case VT_EMPTY:
strValue="1980-08-08";
break;
default:
strValue=(LPCSTR)_bstr_t(vValue);
break;
}
CString strYear,strMonth,strDay,strHour,strMin,strSec;
strYear=strValue.Mid(0,4);
strMonth=strValue.Mid(5,2);
strDay=strValue.Mid(8,2);
if(strValue.GetLength()>10)
{
strHour=strValue.Mid(11,2);
strMin=strValue.Mid(14,2);
strSec=strValue.Mid(17,2);
}
else
{
strHour="0";
strMin="0";
strSec="0";
}
CTime TValue(atoi(strYear),atoi(strMonth),atoi(strDay),atoi(strHour),atoi(strMin),atoi(strSec));
CString str=TValue.Format(strType);
return str;
}
//功能:执行SQL语句(Insert Update delete)
//strSQL:SQL语句
//返回值:TRUE:成功 FALSE:失败
BOOL CADOConn::ExecuteSQL(CString strSQL)
{
try
{
// 是否已经连接数据库
if(m_pConnection == NULL) OnInitCADOConn();
strSQL.TrimLeft();
strSQL.TrimRight();
m_pConnection->Execute(_bstr_t(strSQL),NULL,adCmdText);
return TRUE;
}
catch(_com_error e)
{
AfxMessageBox(e.Description());
return FALSE;
}
}
//功能:退出连接
void CADOConn::ExitConnect()
{
try
{
if (m_pRecordset !=NULL) m_pRecordset->Close();
if (m_pConnection !=NULL) m_pConnection->Close();
// 释放环境
::CoUninitialize();
}
catch (_com_error e)
{
AfxMessageBox(e.Description());
}
}
//功能:向一表中添加一行数据
//strTable:表名
//strSum:表中字段集的数目
//pszText...:strSum个数据字符串
//返回值:TRUE:成功 FALSE:错误
BOOL CADOConn::AddItem(CString strTable,int strSum,LPCTSTR pszText, ... )
{
strTable.TrimLeft();
strTable.TrimRight();
CString strSQL="select * from "+strTable;
CString strFirst=pszText;
LPTSTR* arrpsz = new LPTSTR[strSum];//初始化一列表存放数据
arrpsz[ 0 ] = new TCHAR[ lstrlen( pszText ) + 1 ];
(void)lstrcpy( arrpsz[ 0 ], pszText );
va_list list;
va_start( list, pszText );//向列表填充数据
Open(strSQL);//字符集类型的查找
strSQL="insert into "+strTable+" values(";
int iType;
iType=GetValueType(0);
if (iType==ado_Field_Str||iType==ado_Field_Text||iType==ado_Field_Date)
strSQL=strSQL+"'"+strFirst+"',";//字符型
else
{
if(strFirst=="") strFirst="0";
strSQL=strSQL+strFirst+",";//数字型
}
for( int iColumn = 1; iColumn <strSum; iColumn++ )
{
pszText = va_arg( list, LPCTSTR );
ASSERT_VALID_STRING( pszText );
iType=GetValueType(iColumn);
if (iType==ado_Field_Str||iType==ado_Field_Text||iType==ado_Field_Date)
strSQL=strSQL+"'"+pszText+"',";
else
{
CString strValue=pszText;
if(strValue=="") strValue="0";
strSQL=strSQL+strValue+",";
}
arrpsz[ iColumn ] = new TCHAR[ lstrlen( pszText ) + 1 ];
(void)lstrcpy( arrpsz[ iColumn ], pszText );
}
va_end( list );
//开始执行
strSQL=strSQL.Left(strSQL.GetLength()-1)+")";
try
{
//执行插入操作
m_pConnection->Execute(_bstr_t(strSQL),NULL,adCmdText);
return TRUE;
}
catch(_com_error e)
{
AfxMessageBox(e.Description());
return FALSE;
}
}
//功能:返回索引为Index时的数据的类型
//返回值:数据类型
int CADOConn::GetValueType(int index)
{
_variant_t vIndex;
int Tpye;
vIndex.vt=VT_I2;
vIndex.iVal=index;
Tpye=m_pRecordset->Fields->GetItem(vIndex)->GetType();
return Tpye;
}
//功能:判断字段集是否结束
//返回值:TRUE:结束 FALSE:未结束
BOOL CADOConn::adoEOF()
{
if(m_pRecordset->adoEOF)
return TRUE;
else
return FALSE;
}
//功能:填充列表
//listMain:列表指针 ColOpenEnd:代表展开多少列
//返回值:TRUE:成功 FALSE:失败
BOOL CADOConn::FillList(CListCtrl *listMain,int ColOpenEnd)
{
int i,iType,iRow=0,listWidth=0;//iType:字段集的数据类型 listWidth:列表中列的宽度
long lMax=0;
_variant_t vIndex;
lMax=m_pRecordset->Fields->Count;
vIndex.vt=VT_I2;
listMain->SetExtendedStyle( LVS_EX_FULLROWSELECT);
listMain->DeleteAllItems();
for(i=0;i<100;i++)
listMain->DeleteColumn(i);
for(i=0;i<lMax;i++)
{
CString strTitle="";
vIndex.iVal=i;
strTitle=(LPCTSTR)m_pRecordset->Fields->GetItem(vIndex)->GetName();
listMain->InsertColumn(i,strTitle,LVCFMT_CENTER,100,0);
}
if(!m_pRecordset->adoEOF)
{
MoveFirst();
while (!m_pRecordset->adoEOF)
{
for (i=0;i<lMax;i++)
{
CString strValue="";
vIndex.iVal=i;
iType=m_pRecordset->Fields->GetItem(vIndex)->GetType();
switch(iType)
{
case ado_Field_Str:
case ado_Field_Text:
strValue=GetValueString(i,0);
break;
case ado_Field_Long:
strValue=GetValueLongStr(i,0);
break;
case ado_Field_Int:
strValue=GetValueIntStr(i,0);
break;
case ado_Field_Float:
strValue=GetValueFloatStr(i,0,2);
break;
case ado_Field_Double:
strValue=GetValueDoubleStr(i,0,2);
break;
case ado_Field_Byte:
strValue=GetValueByteStr(i,0);
break;
case ado_Field_Date:
strValue=GetValueString(i,0);
break;
default:
strValue="";
break;
}
if(m_DataType==2)
strValue=GetValueString(i,0);
if(i==0)
listMain->InsertItem(iRow,strValue,0);
else
listMain->SetItemText(iRow,i,strValue);
}
m_pRecordset->MoveNext();
iRow=iRow+1;
}
//移向开头
MoveFirst();
}
if(listMain->GetItemCount()>0)
{
if(ColOpenEnd>0)
{
for(int i=0;i<ColOpenEnd;i++)
{
listMain->SetColumnWidth(i,LVSCW_AUTOSIZE);
listWidth=listMain->GetColumnWidth(i);
listMain->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER);
if(listWidth<listMain->GetColumnWidth(i))
listMain->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER);
}
}
else
{
listMain->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER);
}
}
else
{
for(i=0;i<lMax;i++)
{
listMain->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER);
listWidth=listWidth+listMain->GetColumnWidth(i);
}
RECT rectList;
listMain->GetWindowRect(&rectList);
if(listWidth<(rectList.right-rectList.left))
{
listWidth=(rectList.right-rectList.left-listWidth)/11;
listMain->SetColumnWidth(i,listMain->GetColumnWidth(i)+listWidth);
}
}
return TRUE;
}
//功能:初始化自动排列列表
//CListCtrl:列表指针;colSum:列表中已经存在列数
BOOL CADOConn::InitList(CListCtrl *listMain,int colSum)
{
int intWidth=0;
int i;
for(i=0;i<colSum;i++)
{
listMain->SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER);
intWidth=intWidth+listMain->GetColumnWidth(i);
}
RECT rectList;
listMain->GetWindowRect(&rectList);
if(intWidth<(rectList.right-rectList.left))
{
intWidth=(rectList.right-rectList.left-intWidth)/colSum;
listMain->SetColumnWidth(i,listMain->GetColumnWidth(i)+intWidth);
}
return TRUE;
}
ADOConn.h文件如下:
//使用说明:
//1.构造函数:必须初始化数据库名字,数据库的默认路径为此运行程序的所在路径
//2.结束:必须使用ExitConnect退出
//3.插入、删除、更新:
//4.查询:使用open打开字符集方可使用Get...的函数
//5.填充列表:使用open打开字符集,然后填充
#import "c:\program files\common files\system\ado\msado15.dll" \
no_namespace \
rename ("EOF", "adoEOF")
//返回类型的宏定义
#define ado_Field_Str 202
#define ado_Field_Byte 17
#define ado_Field_Int 2
#define ado_Field_Long 3
#define ado_Field_Float 4
#define ado_Field_Double 5
#define ado_Field_Text 203
#define ado_Field_Date 7
#ifdef _DEBUG
#define ASSERT_VALID_STRING( str ) ASSERT( !IsBadStringPtr( str, 0xfffff ) )
#else // _DEBUG
#define ASSERT_VALID_STRING( str ) ( (void)0 )
#endif // _DEBUG
class CADOConn
{
// 定义变量
public:
//添加一个指向Connection对象的指针:
_ConnectionPtr m_pConnection;
//添加一个指向Recordset对象的指针:
_RecordsetPtr m_pRecordset;
_bstr_t m_strData;
int m_DataType;
CADOConn(CString strData);
CADOConn();
virtual ~CADOConn();
//初始化—连接数据库
void OnInitCADOConn();
//执行查询
_RecordsetPtr& GetRecordSet(CString strSQL);
//执行SQL语句,Insert Update delete
BOOL ExecuteSQL(CString strSQL);
//退出连接
void ExitConnect();
//字段集移向开头
BOOL MoveFirst();
//字段集向下移
BOOL MoveNext();
//打开字段集
BOOL Open(CString strSQL);
//字符串类型(所有类型均可通过此返回此类型的字符串)
CString GetValueString(int index,int strSum);//字符
//字节型整数BYTE
byte GetValueByte(int index);
//短整型数INT
int GetValueInt(int index);
//双精度数DOUBLE
double GetValueDouble(int index);
//单精度数FLOAT
float GetValueFloat(int index);
//长整型数LONG
long GetValueLong(int index);
//时间型CTime
CTime GetValueDate(int index);
//字节型整数BYTE数值字符
CString GetValueByteStr(int index,int strSum);
//短整型数INT数值字符
CString GetValueIntStr(int index,int strSum);
//双精度数DOUBLE数值字符
CString GetValueDoubleStr(int index,int strLSum,int strRSum);
//单精度数FLOAT数值字符
CString GetValueFloatStr(int index,int strLSum,int strRSum);
//长整型数LONG数值字符
CString GetValueLongStr(int index,int strSum);
//时间型CTime数值字符
CString GetValueDateStr(int index,CString strType);
//添加单项数据
BOOL AddItem(CString strTable,int strSum,LPCTSTR pszText, ... );
//得到字段中数据的类型
int GetValueType(int index);
//字段集的结束判断
BOOL adoEOF();
//填充列表(ColOpenEnd代表展开多少列)
BOOL FillList(CListCtrl *listMain,int ColOpenEnd);
//初始化列表
BOOL InitList(CListCtrl *listMain,int colSum);
//得到应用程序所在的文件夹
CString GetAppPath();
};