繁体   English   中英

MS Access中SQL查询的奇怪结果

[英]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)

有人发现我在做什么吗?

题外话:DAO记录集记录数的讨论

直到.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属性作为其常规操作的一部分进行维护。

题外话:ADO记录集的Recordcount的讨论

通过@onedaywhen

对于ADO记录集, RecordCount属性将始终是最终值。 也就是说,与DAO不同,如果您检查其值,则以后将无法更改。 导航EOF不会以任何方式影响ADO的RecordCount值。

即使异步获取记录(DAO记录集不明确支持),也是如此:也就是说,即使记录集尚未满, RecordCount属性仍会反映最终值(而不是到目前为止获取的记录数) DAO)。

CursorLocationCursorType某些组合将使RecordCount始终为-1,这意味着不支持该属性。 但是,再次,它将保持恒定,即如果最初为-1,那么它将始终为-1。

不支持RecordCount的Access数据库引擎的适用组合是adOpenForwardOnlyadOpenDynamic但仅在使用服务器端光标位置时才适用。 (请注意,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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM