<rmcreative>

RSS

Несколько SQL-запросов за один раз через PDO

24 июня 2011

Понадобилось исполнить несколько не однотипных запросов за один раз. Также, как это делает mysqli::multi_query, но через PDO. Сделать это, оказалось, вполне реально, но и без интересностей не обошлось.

Во-первых нагуглить это оказалось почему-то не так просто: вылезали какие-то обсуждения PDO_MYSQLND 2008-го года и, хоть и свежие, но оставшиеся без внятного ответа вопросы на StackOverflow.

Оказалось, что PDO_MYSQLND с релизом PHP 5.3 заменил PDO_MYSQL, который такие вещи не поддерживал. Причём заменил под тем же именем PDO_MYSQL.

Итого, для выполнения нескольких запросов за один раз понадобится:

  • PHP 5.3+
  • mysqlnd
  • Эмуляция prepared statement через PDO::ATTR_EMULATE_PREPARES, выставленный в 1 (по умолчанию) или, как альтернатива, не использование prepared statements и выполнение запроса напрямую через $pdo->exec.

Используем exec

$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
 
// работает как для реальных statement-ов, так и для эмуляции
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
 
$sql = "DELETE FROM car; INSERT INTO car(name, type) VALUES ('car1', 'coupe'); INSERT INTO car(name, type) VALUES ('car2', 'coupe');";
 
try {
    $db->exec($sql);
}
catch(PDOException $e)
{
    echo $e->getMessage();
    die();
}

Используем statement-ы

$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
 
// Не будет работать с реальными statement-ами. Только с эмуляцией.
// Строку ниже можно закомментировать, это умолчание
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
 
$sql = "DELETE FROM car; INSERT INTO car(name, type) VALUES ('car1', 'coupe'); INSERT INTO car(name, type) VALUES ('car2', 'coupe');";
 
try {
    $stmt = $db->prepare($sql);
    $stmt->execute();
}
catch(PDOException $e)
{
    echo $e->getMessage();
    die();
}

Комментарии RSS

  1. №4849
    OZ
    OZ 24 июня 2011 г., 4:17:00

    понадобится: mysqlnd

    это в конфиге как-то прописывать можно?

  2. №4850
    aktuba
    aktuba 24 июня 2011 г., 4:24:25

    А где это может понадобиться? Неужели транзакции сильно проиграют в скорости?

  3. №4851
    Sam
    Sam 24 июня 2011 г., 5:03:12

    OZ, http://www.php.net/manual/en/mysqlnd.install.php.

    aktuba, транзакции разве гарантируют единичную передачу данных? Они ведь не эмулируются, а честно выполняются СУБД.

  4. №4852
    OZ
    OZ 24 июня 2011 г., 5:06:41

    Sam, а какие вкусности ещё даёт mysqlnd? Какие есть минусы? Думаю вот, стоит ли пересобрать. В PDO я нуб.

  5. №4853
    Sam
    Sam 24 июня 2011 г., 5:18:33

    Быстрее, кушает памяти меньше ну и ещё есть разные плюшки. И в PDO тоже.

  6. №4854
    OZ
    OZ 24 июня 2011 г., 5:20:25

    Sam, спасибо. Будем брать :)

  7. №4855
    nex2hex
    nex2hex 24 июня 2011 г., 12:35:50

    Sam, разумеется, транзакции гарантируют что весь запрос выполнится полностью, или не выполнится совсем.

  8. №4856
    Sam
    Sam 24 июня 2011 г., 14:17:53

    nex2hex, это-то ясно. Но сколько раз при этом гоняются данные между PDO и MySQL?

  9. №4858
    Сергей
    Сергей 25 июня 2011 г., 0:38:37
    catch(PDOException $e)
    {
        echo $e->getMessage();
        die();
    }

    Ну вот зачем так писать? Не проще ли не отлавливать исключение?

  10. №12273
    Павел
    Павел 06 окт. 2022 г., 16:18:45

    А у меня проблема с несколькими SQL-запросами за один раз через PDO в MSSQL. На одной машине execute выполняет все запросы, а на второй по одному, приходится делать nextRowset. Не знаю, как решить эту проблему. Может подскажете?

  11. №12275
    Sam
    Sam 15 нояб. 2022 г., 14:56:53

    По идее, разное окружение. Посмотрите PDO::ATTR_EMULATE_PREPARES.

  12. №12276
    Павел
    Павел 15 нояб. 2022 г., 15:06:46

    Этот атрибут не применим для MSSQL

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.