【问题标题】:PDO SQLite query zero result issuePDO SQLite 查询零结果问题
【发布时间】:2015-02-01 11:23:06
【问题描述】:

我环顾四周,但似乎找不到任何关于此的信息。我不确定这是我的代码问题还是内存中 SQLite 数据库和 PDO 的已知问题。

基本上,在内存中的 SQLite 数据库表中插入一行后,我希望与插入的项目不匹配的查询返回零行。但是,以下代码给出了单行 (false) 但没有实际的 PDO 错误代码。

<?php

    // Create the DB
    $dbh = new PDO('sqlite::memory:');
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Data we'll be using
    $name = 'Entry';

    // Create DB table
    $dbh->query('
        CREATE TABLE
            Test
            (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name VARCHAR(50) NOT NULL
            )
    ');

    // Insert data
    $stmt = $dbh->prepare('
        INSERT INTO
            Test
            (
                name
            )
        VALUES
            (
                :name
            )
    ');

    $stmt->bindParam(':name', $name, PDO::PARAM_STR, 50);
    $stmt->execute();

    // Check data has actually been inserted
    $entries = $dbh->query('
        SELECT
            *
        FROM
            Test
    ')->fetchAll(PDO::FETCH_ASSOC);

    var_dump($entries);

    // Query DB for non-existent items
    $stmt = $dbh->prepare('
        SELECT
            *
        FROM
            Test
        WHERE
            name != :name
    ');

    $stmt->bindParam(':name', $name, PDO::PARAM_STR);
    $stmt->execute();

    // How many rows returned
    echo $stmt->rowCount();

    // Actual data returned
    var_dump($stmt->fetch(PDO::FETCH_ASSOC));
?>

我已经设法用一些hackery解决了这个问题,但最好不必这样做:

<?php

    echo (
        (0 == $stmt->rowCount()) || 
        (
            (1 == $stmt->rowCount()) && 
            (false === (($row = $stmt->fetch(PDO::FETCH_ASSOC)))) && 
            ('0000' == array_pop($dbh->errorInfo()))
        )
    ) ? 'true' : 'false';

?>

谁能帮助或指出我可能犯的任何明显错误?

【问题讨论】:

  • 仅仅因为你可以写一个复杂的单个表达式并不意味着你应该。
  • 不确定您指的是代码的哪一部分?作为替代方案,您有什么建议?

标签: php sqlite pdo


【解决方案1】:

PDOStatement::rowCount() 返回

...受相应 PDOStatement 对象执行的最后一个 DELETE、INSERT 或 UPDATE 语句影响的行数。

如果关联 PDOStatement 执行的最后一条 SQL 语句是 SELECT 语句,某些数据库可能会返回该语句返回的行数。但是,这种行为并不能保证适用于所有数据库,并且不应依赖于可移植应用程序。

欢迎来到 PDO,在这里,简单的事情奏效,而不那么简单的事情毁了你的一天。 SQLite 是没有可靠的“我的结果集中有多少行?”的驱动程序之一。功能。来自 cmets:

从 SQLite 3.x 开始,SQLite API 本身发生了变化,现在所有查询都使用“语句”实现。因此,PDO 无法知道 SELECT 结果的行数,因为 SQLite API 本身不提供这种能力。

PDOStatement::fetch() 返回false 是“什么都没有回来”的保证,如果有点难以阅读,您的检查代码是完全正常的。您可能希望考虑包装或派生 PDO 和 PDOStatement 以确保您自己的理智。

(免责声明:我是 PDO 粉丝。)

【讨论】:

  • 谢谢查尔斯。我也是 PDO 的忠实拥护者,并且拥有自己的扩展类,但这源自独立的单元测试,我试图将事情拉回到尽可能简单的状态。
猜你喜欢
  • 1970-01-01
  • 2014-02-25
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
相关资源
最近更新 更多