PDO Parameterized Query - повторно использовать именованные заполнители? - PullRequest
21 голосов
/ 12 марта 2010

По сути, у меня есть значение, которое я должен вызвать пару раз в своем SQL-запросе. Таким образом, возможно ли повторно использовать одноименный заполнитель в утверждении, например, SELECT :Param FROM Table WHERE Column = :Param, затем просто bindValue (": Param"), и у него должно быть значение для обоих: Params?

Ответы [ 4 ]

20 голосов
/ 15 марта 2010

PDO :: prepare гласит, что «нельзя использовать именованный маркер параметра с одним и тем же именем дважды в подготовленном операторе», поэтому я полагаю, что тогда нет.

4 голосов
/ 24 февраля 2017

Вы можете, если вы установите PDO::ATTR_EMULATE_PREPARES = true.

например. $connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);.

Если вы используете Laravel, вы можете установить это в массиве options в config/database.php. например PDO::ATTR_EMULATE_PREPARES => true

2 голосов
/ 03 ноября 2013

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

Этот ответ опубликован анонимным пользователем http://php.net/manual/en/pdo.prepare.php:

Для тех, кто интересуется, почему добавление кавычек вокруг заполнителя неправильно, и почему вы не можете использовать заполнители для имен таблиц или столбцов:

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

План для "ВЫБЕРИТЕ имя ОТ my_table WHERE id =: value" будет То же самое, что вы заменяете на ": значение", но, похоже, похоже «SELECT name FROM: table WHERE id =: value» не может быть запланировано, потому что СУБД понятия не имеет, из какой таблицы вы на самом деле собираетесь выбирать.

Даже при использовании «эмулированной подготовки» PDO не может позволить вам использовать заполнители в любом месте, потому что это должно было бы решить, что вы значит: "Выбрать: foo From some_table" значит ": foo" будет ссылка на столбец или литеральная строка?

Когда в вашем запросе используется динамическая ссылка на столбец, вы должны явно указать белый список столбцов, которые, как вы знаете, существуют в таблице, например, использование оператора switch с исключением, которое выдается в предложении default:

0 голосов
/ 27 апреля 2019

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

SELECT :Param FROM Table WHERE Column = :Param

будет таким же, как

SELECT Column FROM Table WHERE Column = :Param

Но иногда это не так просто. Например:

SELECT *
FROM my_table
WHERE first_name LIKE :Param
   OR last_name  LIKE :Param
   OR biography  LIKE :Param

В этом случае вы можете повторно использовать значение параметра, храня его в производной таблице с перекрестными связями (подзапрос в предложении FROM):

SELECT t.*
FROM my_table t
CROSS JOIN (SELECT :Param as Param) AS x
WHERE first_name LIKE x.Param
   OR last_name  LIKE x.Param
   OR biography  LIKE x.Param
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...