[英]Odd Results from an SQL query in MS Access
好吧,这是我正在运行的MS Access数据库中的一个奇怪数据。
我有一个SQL查询:
SELECT *
FROM [Service Schedule]
WHERE ID=2
AND Volume <= 3000
AND Term='Monthly'
AND special = 'Regular'
ORDER BY volume
将其放入查询生成器的SQL视图中时,我得到2条记录,一条记录的卷为0,一条记录的卷为3000。
当我使用此代码时:
sSQL = "SELECT * FROM [Service Schedule] WHERE ID=2 AND Volume <= 3000 AND Term='Monthly' and special = 'Regular' ORDER BY volume"
Set rsServiceSched = CurrentDb.OpenRecordset(sSQL, dbOpenDynaset, dbSeeChanges)
**要查看我从代码查询中得到的内容,我使用Debug.Print输出recordcount和卷。
我只得到1条记录,一条记录的数量为0。
这是真的很奇怪的地方...
当我将Volume <= 3000更改为Volume <3000时,我得到一条记录(volume = 0)
当我将音量<= 3000更改为音量= 3000时,我得到一条记录(音量= 3000)
有人发现我在做什么吗?
直到.MoveLast之后,才能保证DAO记录集的记录计数准确,但是如果记录集返回了任何记录,则.RecordCount将为1或更大。
请注意,表类型记录集将立即返回准确的.RecordCount,而没有.MoveLast,但是请记住,您无法在链接表上打开表类型记录集。 另外,请小心,不要假定您正在获取所需的记录集类型,除非您已明确指定它。 虽然dbOpenTable是默认的记录集类型,但是如果不能将表或SQL字符串作为表类型的记录集打开,则它将变为打开动态集。 因此,您可以认为您正在使用它来打开表类型记录集,因为table-type是默认值,并且您已经传递了表名:
Set rs = CurrentDB.OpenRecordset("MyTable")
但是您必须记住,仅仅因为您向它传递了一个表,所以它不一定会打开一个表类型的记录集,并且recordcount不一定是准确的。 如果您确实要确定要打开表类型的记录集,则需要明确指定:
Set rs = CurrentDB.OpenRecordset("MyTable", dbOpenTable)
如果“ MyTable”是链接表,则将引发错误。 如果混合使用链接表和本地表,则必须使用两种不同的方法来获取表类型的记录集。 否则(例如,如果您未指定记录集类型,并在可能的情况下将其设置为表类型,而在未指定时设置为动态集),则需要知道何时需要.MoveLast才能获取准确的.RecordCount。 如果您真的想在这种情况下提高效率,请测试记录集的.Type:
Set rs = CurrentDB.OpenRecordset("MyTable")
If rs.Type = dbOpenDynaset Then
rs.MoveLast
End If
那时,无论记录集是以表类型还是动态集打开,您都将具有一个准确的.RecordCount属性。
但是请记住,很少需要使用完整的记录集来获取记录计数。 通常,您只检查.RecordCount即可查看记录集是否返回了任何记录,在这种情况下,您不需要准确的计数。
同样,如果您要遍历完整的记录集,最终将获得准确的RecordCount。 也就是说,这样做是没有意义的:
Set rs = CurrentDB.OpenRecordset("MyTable")
rs.MoveLast
If rs.RecordCount > 0 Then
.MoveFirst
Do Until rs.EOF
[something or other]
.MoveNext
Loop
End If
Debug.Print rs.RecordCount
在那种情况下,.MoveLast是完全不需要的,因为您无需知道代码中该点的确切计数。
另外,请记住,在某些情况下,您确实确实需要知道确切的.RecordCount,仅使用内置的Access DCount()函数或执行以下操作可能会更有效:
Dim lngRecordCount As Long
lngRecordCount = CurrentDB.OpenRecordset("SELECT COUNT(*) FROM MyTable")(0)
要么:
lngRecordCount = DBEngine.OpenDatabase(Mid(CurrentDB.TableDefs("MyTable").Connect, 11)).TableDefs("MyTable").RecordCount
有各种各样有效的快捷方式可以获取准确的RecordCount,而无需强制记录集指针移动到最后一条记录。
顺便说一句,纯Table-Type记录的RecordCount准确的原因之一是因为不必进行计算-Jet / ACE将RecordCount属性作为其常规操作的一部分进行维护。
通过@onedaywhen
对于ADO记录集, RecordCount
属性将始终是最终值。 也就是说,与DAO不同,如果您检查其值,则以后将无法更改。 导航EOF
不会以任何方式影响ADO的RecordCount
值。
即使异步获取记录(DAO记录集不明确支持),也是如此:也就是说,即使记录集尚未满, RecordCount
属性仍会反映最终值(而不是到目前为止获取的记录数) DAO)。
CursorLocation
和CursorType
某些组合将使RecordCount
始终为-1,这意味着不支持该属性。 但是,再次,它将保持恒定,即如果最初为-1,那么它将始终为-1。
不支持RecordCount
的Access数据库引擎的适用组合是adOpenForwardOnly
和adOpenDynamic
但仅在使用服务器端光标位置时才适用。 (请注意,Access数据库引擎实际上并不支持动态游标: adOpenDynamic
过载了,以便用户向记录引擎的Source
是动态SQL代码的引擎提供优化“提示”)。
请注意,设置记录集的Filter
属性将更改RecordCount
以反映应用过滤器后的记录数。
我不确定您要为该表的PK值做什么,但是当您说:“ ID = 2”时,这听起来像是我的鱼,因为我总是使用代理键(从不自然),而ID始终是PK。 由于您没有加入任何表,因此这告诉我您应该始终从结果中期待一行/元组。
如果ID不是您的PK,您可以通过评论让我知道吗?
也许您需要使用以下方法迭代结果集:Set.MoveNext
听起来您希望“查看”所有记录,但是我认为您只是在检索第一个记录。 我说这是因为您看到的是每种情况的第一笔记录。 您可能需要移动到记录集中的下一条记录才能查看下一条。
rsServiceSched.MoveNext
您可能没有遍历结果集。 rsServiceSched仅指向第一个记录,该记录将是最小记录(您的order by子句的购买)。 现在您需要对此进行处理,然后进入下一个记录
这个例子可能对您有帮助...
这是DAO,您需要移动到最后以获取完整的记录数; 否则,如果记录存在,您将只得到1,否则就得到0。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.