PDO SQLite запрос нулевой результат выдачи - PullRequest
4 голосов
/ 14 января 2011

Я осмотрелся, но не могу найти никакой информации по этому вопросу.Я не уверен, что это проблема с моим кодом или известная проблема с базами данных 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));
?>

Мне удалось обойти проблему с некоторыми хакерскими атаками, но было бы неплохо не иметьчтобы сделать это:

<?php

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

?>

Может ли кто-нибудь помочь или указать на какие-либо явные ошибки, которые я мог совершить?

1 Ответ

13 голосов
/ 15 января 2011

PDOStatement :: rowCount () возвращает

... количество строк, затронутых последним оператором DELETE, INSERT или UPDATE , выполненным соответствующим объектом PDOStatement.

Если последний оператор SQL, выполненный связанным PDOStatement, был оператором SELECT, некоторые базы данных могут возвращать количество строк, возвращаемых этим оператором . Однако это поведение не гарантируется для всех баз данных и не должно использоваться для переносимых приложений.

Добро пожаловать в PDO, где работают легкие вещи, а непростые вещи разрушают ваш день. SQLite - один из драйверов, который не имеет надежного "сколько строк в моем наборе результатов?" функция. Из комментариев:

Начиная с SQLite 3.x, сам API SQLite изменился, и теперь все запросы реализуются с использованием «операторов». Из-за этого PDO не может узнать rowCount результата SELECT, потому что сам SQLite API не предоставляет такую ​​возможность.

Возвращение false из PDOStatement :: fetch () является гарантией «ничего не вернулось», и ваш проверочный код совершенно нормален, если его немного трудно прочитать. Вы можете рассмотреть возможность переноса или извлечения из PDO и PDOStatement для вашего собственного здравомыслия.

(Отказ от ответственности: я фанат PDO.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...