SQL Server连接方式之ADO
概要:
已经用ADO写了两个小的数据库更改小程序,现在记录下自己学习ADO过程中的心得和要点。
ADO是对OLE DB技术的上层封装,是基于通用对象模型(COM)的,提供了多语言的访问技术。
要点:
--连接COM库:
使用的连接语句是:
#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF", "EndOfFile")
PS:要求是上述语句在一行中
msado15.dll是系统的库,如果缺失的话可再安装
--ADO对象模型:
ADO包含三个基本接口:_ConnectionPtr,_CommandPtr,_RecordsetPtr。
_ConnectionPtr:创建数据库连接或执行不返回任何结果的SQL语句(如存储过程);
_CommandPtr:返回一个记录集,提供一个简单的方法来执行返回记录集的存储
过程和SQL语句。
_RecordsetPtr:是一个记录集对象,对记录集提供了更多的控制功能。
--数据类型:
主要有_variant_t(结果)和_bstr_t(参数)两种COM类型
_variant_t类型:
_variant_t value;
if(value.vt != VT_NULL) --_variant_t不为空
可通过value.lValue等方法获取相应的数据,网上查到的一个方式是先通过类型判断包含的值类型再通过不同的数据成员获取数值;
同时_variant_t定义了很多转换函数可直接使用强制类型转换;
需要注意的是字符串类型的转换问题--需要先转化为_bstr_t类型;
_bstr_t类型:
可看作是一种字符串类型,可以直接构造参数为字符串的_bstr_t类型对象。
--API接口:
·初始化ADO环境:
::CoInitialize(NULL) --初始化
::CoUninitialize() --反初始化
·创建实例:
_ConnectionPtr myDb; myDb.CreateInstance(__uuidof(Connection));
_RecordsetPtr mySet; mySet.CreateInstance(__uuidof(Recordset));
·连接数据库:
连接数据库分为两种方法:基于DSN方法和基于非DSN方法
基于DSN方法:
myDb->open("DSN=dsn;UID=admin;PWD=admin","","",-1);
基于非DSN方法:
myDb->open("Provider=SQLOLEDB;SERVER=svr;DATABASE=samp"
,"","",-1);
·执行SQL语句:
_ConnectionPtr和_RecordsetPtr都可执行SQL语句
mySet->open("select * from table",myDb.GetInterfacePtr(),
adOpenDynamic,adLockOptimistic,adCmdText);
·判断是否读取到结果集的末尾:
while(!mySet->EndOfFile){}
·获取结果:
_variant_t rst=mySet->GetCollect("col_name");
·移动光标:
mySet->MoveNext();
·异常:
捕获的异常是_com_error;
小结:
学习ODBC和ADO的时候发现执行的过程总是很相似的--模版啊。
摘抄:
//_variant_t转WORD类型
BOOL AfxVariantConvert(WORD& val, const _variant_t& vt)
{
if (vt.vt == VT_UI2)
{
val = (WORD)vt.uiVal;
return TRUE;
}
else
{
val = 0;
return FALSE;
}
}
_variant_t转DWORD类型
BOOL AfxVariantConvert(DWORD& val, const _variant_t& vt)
{
if (vt.vt == VT_UI4 )
{
val = (DWORD)vt.ulVal;
return TRUE;
}
else
{
val = 0;
return FALSE;
}
}
_variant_t转DWORD64类型
BOOL AfxVariantConvert(DWORD64& val, const _variant_t& vt)
{
if (vt.vt != VT_UI8 )
{
val = (DWORD64)vt.ullVal;
return TRUE;
}
else
{
val = 0;
return FALSE;
}
}
_variant_t转CString类型
BOOL AfxVariantConvert(CString& val, const _variant_t& vt)
{
if (vt.vt == VT_BSTR)
{
val = (LPCTSTR)vt.bstrVal;
return TRUE;
}
else
{
val = _T("");
return FALSE;
}
}
_variant_t转BOOL类型
BOOL AfxVariantConvert(BOOL& val, const _variant_t& vt)
{
if (vt.vt == VT_BOOL)
{
val = vt.boolVal;
return TRUE;
}
else
{
val = FALSE;
return FALSE;
}
}
_variant_t转CTime类型(精度变短,可能丢失数据)
BOOL AfxVariantConvert(CTime& val, const _variant_t& vt)
{
if (vt.vt == VT_DATE)
{
val = vt.date;
return TRUE;
}
else
{
val = NULL;
return FALSE;
}
}
_variant_t转double类型
BOOL AfxVariantConvert(DOUBLE& val, const _variant_t& vt)
{
if (vt.vt == VT_R8)
{
val = vt.dblVal;
return TRUE;
}
else
{
val = 0;
return FALSE;
}
}
_variant_t转byte类型
BOOL AfxVariantConvert(BYTE& val, const _variant_t& vt)
{
if (vt.vt == VT_UI1 || vt.vt == VT_I1)
{
val = vt.bVal;
return TRUE;
}
else
{
val = 0;
return FALSE;
}
}
_variant_t转float类型
BOOL AfxVariantConvert( FLOAT& val, const _variant_t& vt )
{
if (vt.vt == VT_R4)
{
val = vt.fltVal;
return TRUE;
}
else
{
val = 0;
return FALSE;
}
}
_variant_t转long类型
BOOL AfxVariantConvert( long& val,const _variant_t& vt )
{
if (vt.vt == VT_I4)
{
val = vt.lVal;
return TRUE;
}
else
{
val = 0;
return FALSE;
}
}
_variant_t转INT64类型
BOOL AfxVariantConvert( INT64& val,const _variant_t& vt )
{
if (vt.vt == VT_I8)
{
val = vt.llVal;
return TRUE;
}
else
{
val = 0;
return FALSE;
}
}