Несколько 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 по email OK
это в конфиге как-то прописывать можно?
А где это может понадобиться? Неужели транзакции сильно проиграют в скорости?
OZ, http://www.php.net/manual/en/mysqlnd.install.php.
aktuba, транзакции разве гарантируют единичную передачу данных? Они ведь не эмулируются, а честно выполняются СУБД.
Sam, а какие вкусности ещё даёт mysqlnd? Какие есть минусы? Думаю вот, стоит ли пересобрать. В PDO я нуб.
Быстрее, кушает памяти меньше ну и ещё есть разные плюшки. И в PDO тоже.
Sam, спасибо. Будем брать :)
Sam, разумеется, транзакции гарантируют что весь запрос выполнится полностью, или не выполнится совсем.
nex2hex, это-то ясно. Но сколько раз при этом гоняются данные между PDO и MySQL?
Ну вот зачем так писать? Не проще ли не отлавливать исключение?
А у меня проблема с несколькими SQL-запросами за один раз через PDO в MSSQL. На одной машине execute выполняет все запросы, а на второй по одному, приходится делать nextRowset. Не знаю, как решить эту проблему. Может подскажете?
По идее, разное окружение. Посмотрите
PDO::ATTR_EMULATE_PREPARES
.Этот атрибут не применим для MSSQL