【问题标题】:PHP and MS Access: Number of Records returned by SELECT queryPHP 和 MS 访问:SELECT 查询返回的记录数
【发布时间】:2010-09-12 16:40:24
【问题描述】:

我正在运行 PHP 代码以与 MS Access 数据库进行交互。

$odbc_con = new COM("ADODB.Connection");
$constr = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" . $db_path . ";";
$odbc_con -> open($constr);

$rs_select = $odbc_con -> execute ("SELECT * FROM Main");

尽管查询返回非零记录,但使用 ($rs_select -> RecordCount) 会给出 -1。

(a) 可能是什么原因? (b) 有什么出路吗?

我也尝试过使用count($rs_select -> GetRows())。这满足了需求,但看起来效率低下,因为它需要首先将所有记录复制到一个数组中。

【问题讨论】:

  • 这里不涉及MS Access,只涉及Jet数据库引擎。

标签: php database ms-access


【解决方案1】:

ADODB 对于返回的记录计数有自己的规则,具体取决于您定义的记录集的类型。见:

MS Knowledge Base article 194973

W3C Schools article

在上面的示例中,PHP COM() 对象用于实例化 ADODB,这是一个用于通用数据库访问的 COM 接口。根据PHP documentation,产生的对象引用是重载的,因此您可以使用与本机 ADODB 对象相同的属性/方法。这意味着您需要使用 ADODB 方法将记录集类型设置为能够提供准确记录计数的类型(如果您必须拥有它)。正如其他人所提到的,另一种方法是使用第二个查询来获取 SELECT 语句返回的记录的 COUNT()。这更容易,但在特定环境中可能不合适。

我不是 ADO 专家,因此无法为您提供设置记录集类型的确切命令,但从上面引用的文章中,很明显您需要静态或键集游标。在我看来,设置 CursorType 的正确方法是在打开记录集的命令中使用参数。 This W3C Schools article on the CursorType property 为该命令提供适当的参数。

希望这些信息能以某种方式帮助原始发帖人完成他的任务。

【讨论】:

    【解决方案2】:

    如果您使用的是动态游标类型的连接,那么它实际上可能会发生变化。当您浏览记录页面时,有人可能会从该数据库中删除记录。为避免这种情况,请使用静态类型的快照游标。我有这个书签,它会很好地解释它。这总是让我着迷,书签总是提醒我为什么。

    http://support.microsoft.com/kb/194973

    【讨论】:

    • ...但是 Jet 不支持动态游标!当请求动态游标时,您会得到一个键集游标,但其含义被覆盖为“我正在使用动态 SQL”(与准备好的语句或存储过程相反),并且引擎会相应地进行优化,即请求动态游标是好东西。
    【解决方案3】:

    基本上,Access 不会在需要时向您显示整个记录集(无论如何,对于大部分用户体验来说,这种方式更快) - 特别是对于较大的记录集。

    要获得准确的计数,您必须遍历整个记录集。在 VBA 中,我通常使用 foo.MoveLast 和 foo.MoveFirst 的二重奏来做到这一点——我不知道 php 的等价物是什么。它很贵,但听起来你无论如何都要处理整个记录集,我想没关系。

    (附带说明,如果您在 VBA 中操作书签,则同样的遍历也是必要的,因为如果您克隆记录集并且在将书签复制回表单的记录集之前不遍历它,则可能会得到一些疯狂的结果)

    【讨论】:

    • 这实际上取决于您使用的数据接口。如果返回记录,则 DAO 记录集返回 1 或更多的记录计数,如果没有返回记录,则返回 0,但在您发出 .MoveLast 命令之前,不能相信记录计数是准确的。 ADO 和 ODBC 是不同的。
    【解决方案4】:

    可能 ODBC 还不知道记录数。在这种情况下,可以转到最后一条记录,然后记录计数才会反映真实的记录数。这也可能不是很有效,因为它会从查询中加载所有记录。

    正如 Oli 所说,使用 SELECT COUNT(*) 会给你结果。我认为使用 2 个查询仍然比使用我的第一个方法更有效。

    【讨论】:

      【解决方案5】:

      Access 没有自己的 COUNT 运算符吗?例如:

      $rs_select = $odbc_con -> execute ("SELECT COUNT(*) FROM Main");
      

      【讨论】:

      • 这是不希望的,因为它会导致多个 SQL 查询 - 一个获取计数,另一个获取记录。目标是检索记录集并检查其记录数以对其进行验证。
      • 我能看到的唯一其他选项(你也已经看到了)涉及不必要地发送大量数据来计算它。触发一个额外的小查询似乎更合理。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多