Разница между exec и execute в переполнении стека

Я изучаю php, но в учебнике, который я использую, я вижу что-то вроде этих строк:

$DatabaseAdd->exec('INSERT INTO db_name......

и этот :

$request->execute(array(.....

Есть ли разница между exec и execute? Можем ли мы использовать один, чтобы заменить другой?

5

Решение

ТЛ; др

  • использование PDO::exec выдавать разовые неподготовленные операторы, которые не возвращают наборы результатов.
  • использование PDO::query выдавать разовые неподготовленные операторы, которые возвращают наборы результатов.

Оба из них полезны, если операторы выполняются только один раз и / или если они построены динамически таким образом, который не поддерживается подготовленными операторами. Обычно требуются дополнительные инструменты для правильного построения операторов (и избегания таких вещей, как уязвимости SQL-инъекций). Это в сочетании с тем фактом, что их гибкость редко требуется, означает, что часто предпочитают:

  • использование PDOStatement::prepare а также PDOStatement::execute готовить заявления и выполнять их независимо от того, возвращают ли они результаты или нет. Полезно, если выполняется несколько раз и / или по горячему пути. Также не требуется дополнительных инструментов для обработки построения операторов. Почти всегда рекомендуется, когда это возможно.

exec а также query действовать на PDO объекты и, следовательно, только в контексте связи. exec используется для операторов, которые не возвращают набор результатов (например, INSERT, UPDATE, DELETE) в то время как query вернет наборы результатов (например, из SELECT заявление). Это просто два одинаковых интерфейса, которые делают одно и то же (выдают оператор). Операторы SQL передаются на сервер как есть и поэтому могут рассматриваться как динамические с точки зрения клиента.

Это означает, что в теории они всегда (т.е. при каждом вызове) могут быть проанализированы, интерпретированы / скомпилированы и оптимизированы для плана запроса СУБД перед выполнением. Это дорого с точки зрения производительности, если они выполняются несколько раз.

На практике они часто кэшируются и используются повторно, если выполняются несколько раз, но СУБД может делать это только условно и без каких-либо гарантий. В зависимости от того, как они сопоставляются, для незначительного изменения запроса может потребоваться, чтобы СУБД полностью его перекомпилировала. Иногда клиент будет строить запрос динамически (слишком часто с помощью примитивных конкатенаций строк, иногда с правильным языка на основе или же библиотека на основе инструментальная поддержка), так что СУБД просто не может кэшировать план запроса.

Обновление: для любопытных, Pinq пример построителя запросов на основе языка для PHP и Учение ЛДБАЛ это библиотечный пример. Обратите внимание, что Pinq анализирует только выражения PHP для предикатов (кажется) и все еще использует свободный API в остальном (хотя некоторые считают, что свободные интерфейсы могут образовывать типы DSL,).

С надлежащим инструментарием и / или когда оператор выполняется только один раз (или очень мало раз), это хорошо и иногда необходимо.

Для случаев, когда вы знать вы будете выдавать один и тот же оператор несколько раз, только возможно с разными параметрами (например, другое значение в предикате /WHERE пункт), не было бы замечательно, если бы был способ сообщить об этом СУБД, чтобы он точно не отбросил весь план запроса? Это также может позволить ему выполнять более тяжелую оптимизацию, чем в противном случае, поскольку у него больше времени для подготовки оператора (фаза медленной инициализации) до его выполнения (возможно, по горячему пути).

Большинство систем баз данных предлагают эту возможность в виде готовые заявления (с использованием различных механизмов, нестандартных AFAIK). ЗОП разоблачает это единым образом через prepare метод, который возвращает другой объект который представляет подготовленное заявление.

Затем вы можете повторно использовать этот объект и особенно его execute метод (который выдает оператор СУБД для выполнения ранее подготовленного оператора). Если оператор параметризован, вы можете даже передать новые параметры для каждого execute вызов.

Это также заставляет вас использовать достаточно подходящий инструментарий для построения ваших заявлений и их выдачи. Как я упоминал ранее, базовая конкатенация строк и другие специальные методы помогут вам продвинуться далеко вперед, прежде чем вы застрелите себя в ногу, скорее всего, из-за неудачи побег динамические части / параметры правильно. Это источник № 1 SQL-инъекция уязвимости.

Обратите внимание, что если инструкция возвращает набор результатов (например, SELECT), вам нужно будет использовать различные fetch варианты для получения результатов.

$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
$result = $sth->fetchAll();
print_r($result);

(Источник)

Также обратите внимание, что очень смущает, query сам возвращает свои результаты в виде PDOStatement объект (так же, как те, которые возвращаются prepare). Хотя можно понять, почему этот интерфейс используется здесь снова, это, вероятно, не лучший дизайн (если не сказать больше). Например, и хотя (а) он явно не задокументирован и (б) я не проверял его, я бы предположил, что execute на PDOStatement вернулся query незаконно (выдает ошибку).

Отказ от ответственности: только интерпретация документов, больше не частый пользователь.

Похожие вопросы:

12

Другие решения

PDO :: exec () выполняет оператор SQL в одном вызове функции, возвращая количество строк, затронутых оператором.

Таким образом, даже если вы использовали «SELECT», вы не получите результаты обратно. Есть смысл?

http://php.net/manual/en/pdo.exec.php

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector