在数据库中,采用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_error e)
{
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_t bstrSQL)
{
try
{
m_pConnection->Execute(bstrSQL,NULL,adCmdText);
return true;
}
catch(_com_error e)
{
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_error e)
{
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_error e)
{
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;