☰
Rs.recordcount=-1 的解决办法:从 ADO 游标到 TaoToken 配置排查
2026/9/29 22:31:58 网站建设 项目流程

1. 为什么你的 Rs.RecordCount 总是 -1

如果你在用 ADO 连数据库,代码里写了If Rs.RecordCount > 0 Then,结果死活进不去分支,打印出来一看Rs.RecordCount等于 -1,那这篇就是写给你的。Rs.RecordCount = -1不是一个 bug,而是 ADO 在告诉你:当前这个记录集,我根本没法确定它有多少条记录。它可能压根没数,也可能游标类型不支持计数,还可能连接串里某个参数把游标能力阉割了。

这个现象在 VB6、VBA、ASP 老项目里特别常见,尤其是从别人手里接过来的代码,连接字符串一长串,游标设置藏在某个角落。很多人第一反应是去改 SQL,加COUNT(*),但那是绕路。真正要解决的是让 ADO 愿意并且能够给你一个准确的记录数。核心就两个开关:CursorLocation和CursorType。把这两个配对,RecordCount大概率立刻从 -1 变成真实条数。

我试过在一个老 ERP 的报表模块里排查这个问题,前后折腾了两小时,最后发现就是CursorLocation默认用了服务端游标,而服务端游标对RecordCount的支持取决于驱动,很多驱动直接返回 -1。改成客户端游标后,一行代码解决。所以这篇会从原理讲到可复制的配置,再顺带把 TaoToken 统一 Key/API 通道的配置文件排查思路串起来——因为现在很多项目是「老 ADO 连库 + 新 AI 接口调用」混着用,配置排查的套路是相通的。

适合谁看:正在维护 VB6/VBA/ASP 老系统、被RecordCount坑过的开发者;以及用 TaoToken 做统一模型接入、需要排查配置文件里 Key 和通道是否生效的同学。下面直接上可复制的代码和验证步骤。

2. 先搞懂 CursorLocation 与 CursorType 的配对关系

RecordCount返回 -1 的根因,九成出在游标。ADO 的游标有两个维度:游标位置(CursorLocation)和游标类型(CursorType)。它们决定了记录集能不能被计数、能不能前后滚动、对数据变化敏不敏感。

CursorLocation有两个常用值:

常量值含义对 RecordCount 的影响
adUseServer2默认值,用数据提供者/驱动的游标取决于驱动,很多返回 -1
adUseClient3用本地游标库的客户端游标通常能返回准确计数

CursorType常用值:

常量值含义RecordCount 行为
adOpenForwardOnly0仅向前游标,默认返回 -1
adOpenStatic3静态游标,数据快照返回实际计数
adOpenKeyset1键集游标返回实际计数
adOpenDynamic2动态游标取决于数据源,可能 -1

关键结论:仅向前游标一定返回 -1,这是设计如此,不是错误。静态游标和键集游标返回真实计数。而CursorLocation设成adUseClient后,本地游标库会帮你把记录集完整拉下来,RecordCount自然就准了。

这里有个容易踩的坑:CursorLocation必须在记录集打开之前设置,而且对已经打开的连接改它没用。文档里写得很清楚——该属性设置仅对属性已经设置后才建立的连接有影响,更改它不会影响现有连接。所以顺序是:先设CursorLocation,再Open记录集。

另一个坑:CursorLocation对Connection或关闭的Recordset是读/写,对打开的Recordset是只读。你如果在Rs.Open之后才写Rs.CursorLocation = 3,要么报错,要么静默无效。

理解了这层,下面的配置片段你就能看懂每一行为什么这么写。

3. 可复制的连接字符串与游标设置片段

先给一个最小可用的 VB6/VBA 片段,直接抄:

Dim Conn As ADODB.Connection Dim Rs As ADODB.Recordset Dim ConnStr As String ' 连接字符串:按你的实际数据库替换 Server/Database/UID/PWD ConnStr = "Provider=SQLOLEDB;Data Source=127.0.0.1;" & _ "Initial Catalog=MyDB;User ID=sa;Password=YourPwd;" Set Conn = New ADODB.Connection Conn.CursorLocation = adUseClient ' 关键:连接级别先设客户端游标 Conn.Open ConnStr Set Rs = New ADODB.Recordset ' 关键:静态游标 + 客户端游标,RecordCount 才准 Rs.CursorLocation = adUseClient Rs.Open "SELECT * FROM Orders WHERE Status=1", Conn, _ adOpenStatic, adLockReadOnly Debug.Print "RecordCount = " & Rs.RecordCount ' 现在应该是真实条数

几个要点:

Conn.CursorLocation = adUseClient写在Conn.Open之前。这样由Execute方法返回的游标会继承该设置,Recordset也会自动从关联的连接继承。

Rs.Open的第三个参数用adOpenStatic(值 3),第四个参数用adLockReadOnly(值 1)。只读锁不会影响计数,还能减少资源消耗。

如果你不想用常量名(有些老环境没引用 ADO 常量库),可以直接写数字:

Conn.CursorLocation = 3 Rs.CursorLocation = 3 Rs.Open "SELECT * FROM Orders WHERE Status=1", Conn, 3, 1

3就是adUseClient,adOpenStatic也是3,adLockReadOnly是1。注意别把两个 3 搞混,一个是位置,一个是类型。

对于 ASP 场景,写法一样,只是变量声明去掉类型:

Set Conn = Server.CreateObject("ADODB.Connection") Conn.CursorLocation = 3 Conn.Open ConnStr Set Rs = Server.CreateObject("ADODB.Recordset") Rs.CursorLocation = 3 Rs.Open sql, Conn, 3, 1 Response.Write Rs.RecordCount

现在把视角切到 TaoToken 这边。很多项目现在是「老 ADO 查库 + 新接口调模型」的混合架构,TaoToken 作为统一 Key/API 通道,配置文件里同样有「通道选择」的概念——你选错了通道,就像选错了游标,拿不到想要的结果。TaoToken 的接入文档在https://taotoken.net/doc,API 基址是https://taotoken.net/api。配置文件里通常要确认三件事:Key 是否正确、base_url 是否指向统一通道、模型名是否在支持列表里。这三件事和 ADO 的「连接串、游标位置、游标类型」是一一对应的排查逻辑。

4. 验证 RecordCount 是否恢复正常

改完配置别急着上线,按下面步骤验证。

第一步,写一个最小测试脚本,只查一张小表,打印RecordCount和实际行数对比:

Rs.Open "SELECT COUNT(*) AS Cnt FROM Orders", Conn, 3, 1 Dim RealCount As Long RealCount = Rs("Cnt").Value Rs.Close Rs.Open "SELECT * FROM Orders", Conn, 3, 1 Debug.Print "RecordCount=" & Rs.RecordCount & " / RealCount=" & RealCount

如果两个数字相等,说明游标配置生效。如果RecordCount还是 -1,往下看排查章节。

第二步,验证Supports能力。ADO 提供Supports方法告诉你当前游标支持哪些功能:

Debug.Print "Bookmark: " & Rs.Supports(adBookmark) Debug.Print "ApproxPosition: " & Rs.Supports(adApproxPosition)

如果adApproxPosition或adBookmark返回 True,那么RecordCount会是精确值。返回 False 就说明游标能力不够,回去检查CursorType是不是还是adOpenForwardOnly。

第三步,如果你在用 TaoToken 调模型做数据摘要,验证通道是否通:

curl https://taotoken.net/api/v1/models \ -H "Authorization: Bearer $TAOTOKEN_API_KEY"

返回模型列表说明 Key 和通道正常。这一步和 ADO 验证RecordCount是一个道理——先确认「通道」通不通,再谈业务逻辑。TaoToken 的模型对话入口在https://taotoken.net/chat,可以拿它快速试一条请求,确认返回正常。

第四步,把验证脚本跑三遍:小表、中表、带 WHERE 条件的表。有些驱动对带条件的查询计数行为不同,多测几种才稳。

5. 本篇常见错误排查清单

下面这些是我和同事实际踩过的,按出现频率排序。

错误一:CursorLocation写在Open之后。这是最高频的。Rs.Open之后再设Rs.CursorLocation,对已打开的记录集是只读,改了不生效。解决:把设置挪到Open之前。

错误二:只设了Rs.CursorLocation,没设Conn.CursorLocation。有些驱动下,连接级别的游标位置会覆盖记录集级别。稳妥做法是两个都设成adUseClient。

错误三:CursorType还是默认的adOpenForwardOnly。仅向前游标永远返回 -1,这是规范。必须显式传adOpenStatic或adOpenKeyset。

错误四:连接字符串里带了Cursor Location之类的参数冲突。某些 Provider 的连接串支持游标相关参数,和代码里的设置打架。排查时先把连接串精简到最小,只留 Provider、Data Source、Initial Catalog、认证信息。

错误五:RecordCount在关闭的记录集上读取。读已关闭的Recordset的RecordCount会产生错误,不是返回 -1。如果你看到的是报错而不是 -1,检查是不是Rs.Close之后还在读。

错误六:TaoToken 配置文件里 base_url 写成了首页而不是 API 地址。统一通道的 API 基址是https://taotoken.net/api,不是官网首页。写错了会 404 或鉴权失败。Key 的管理入口在https://taotoken.net/api-keys,确认 Key 没过期、没超额。

错误七:模型名拼错或不在支持列表。和 ADO 里表名写错一样,通道通了但请求失败。先用模型列表接口确认可用模型名。

错误八:客户端游标拉全表导致内存暴涨。adUseClient+adOpenStatic会把整个结果集拉到本地。如果表很大,RecordCount是准了,但内存也上去了。这时候要么加WHERE缩小范围,要么改用SELECT COUNT(*)单独取数,别为了一个计数把百万行拉进内存。

排查顺序建议:先确认CursorLocation和CursorType的设置位置和值,再用Supports验证游标能力,最后才怀疑驱动和连接串。大部分问题在前两步就解决了。

6. 把游标思路迁移到 TaoToken 配置排查

ADO 的RecordCount = -1教会我们一件事:结果不对,先查通道配置,再查业务逻辑。游标位置和类型就是 ADO 的「通道」,选错了通道,数据能力就被限制。TaoToken 的统一 Key/API 通道也是同样的道理——Key、base_url、模型名三者对齐,请求才通。

如果你在维护长期编码项目或者 Agent 类应用,需要稳定的模型调用通道,可以看下 Coding Plan:https://taotoken.net/coding-plan。它适合把模型接入到日常开发流里,配合统一的 Key 管理,省去每个项目单独配 Key 的麻烦。接入相关的文档都在https://taotoken.net/doc,API Key 在https://taotoken.net/api-keys管理。Claude Code 相关的接入说明在https://taotoken.net/claude-code-anthropic。

回到 ADO 本身,最后留一个实用习惯:把游标设置封装成一个函数,所有记录集打开都走它,避免每处Open都手写参数漏掉。这样RecordCount返回 -1 的概率会降到几乎为零。老代码维护最怕的就是散落各处的隐式默认值,把它们显式化,问题就少一大半。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询