GetRecordCount的使用问题在技术社区里也讨论很多次,一般的建议都是尽量不使用这个函数,要使用也是先通过循环MoveFirst、MoveNext遍历后在使用。但是这样感觉很麻烦也不是很安全,因为如果没有记录很难保证MoveFirst不抛出异常,当然也可以使用try{...}、catch(_com_error &e){...}方式来捕捉异常。所以另一钟更常见的方式就是使用select count(*) as tatol from table查询语句,然后用GetCollect方法(ADO)取得total的值来得到。
在很多时候,我们又很需要GetRecordCount函数来快速判断一个打开的记录集里面总共有多少条记录。我一般是使用ADO方式操作数据库,所以这里谈的很多情况只适合ADO方式。
先看个问题:
_ConnectionPtr m_pCon;
_RecordsetPtr m_pSet;
m_pSet.CreateInstance("ADO.Record");
m_pCon.CreateInstance("ADO.Connect");
m_pCon->Open("DSN=***;.....);//连接到一个设置好的DSN名称,后面的参数就不写啦
m_pSet->Open();//这里打开一个表
关键位置:
if(m_pSet->GetRecordCount() != 0)//如果记录条数不为0
{
//控制操作记录
}
以上代码能够完全正常的运行,后来把连接的语句换为了:
m_pCon->Open("provider=sqloledb;.....); //换了一种数据库连接提供者
却发现查不到任何的数据,跟踪发现GetRecordCount()返回值变成了-1,而且记录集里也有记录存在。后来通过查MSDN解决了问题。
一般情况下当ADO不能确定记录条数,或者连接提供者、游标类型都不支持RecordCount的时候,RecordCount属性都将返回-1。而在一个已经关闭了的Recordset上读取这个属性会引起错误。
最常用的两个游标类型是:
adUseClient
使用由本地游标库提供的客户端游标。本地游标引擎通常允许使用的许多功能可能是驱动程序提供的游标无法使用的,因此使用该设置对于那些将要启用的功能是有好处的。adUseClientBatch与 adUseClient同义,也支持向后兼容性。
adUseServer
默认值。使用数据提供者或驱动程序提供的游标。这些游标有时非常灵活,对于其他用户对数据源所作的更改具有额外的敏感性。但是,Microsoft Client Cursor Provider(如已断开关联的记录集)的某些功能无法由服务器端游标模拟,通过该设置将无法使用这些功能。
这是MSDN上的解释,补充说明:使用adUseClient就是表示数据需要传输到客户端后再进行操作,不具有同步。它能更好的支持RecordCount属性,这样对性能的影响比较大,如果数据很多会更明显。adUseServer是直接在数据库中操作,处理的速度比较快。在其他的很多方面adUesServer很有限制。
再回来看RecordCount,已经记录集的游标类型会影响记录条数的确定,除了上面提到的两种,只支持向前滚动的游标也会返回-1,对静态的指针会返回实际的记录条数,而对一个动态的游标返回值是-1还是实际的条数取决于数据源,正如我上面遇到的问题,使用DSN能正确的返回,而SQLOLEDB不行。
为了使用RecordCount属性,我们需要使用设置好游标(静态/客户):
在m_pSet->Open()前加上:
m_pSet->CursorType = adOpenStatic;
m_pSet->CursorLocation = adUseClient;
完了,呵呵,说得好乱啊,是想到什么写什么!