Как установить параметры ORDER BY, используя подготовленный оператор PDO? - PullRequest
30 голосов
/ 30 марта 2010

У меня проблемы с использованием параметров в разделе ORDER BY моего SQL. Он не выдает никаких предупреждений, но ничего не печатает.

$order = 'columnName';
$direction = 'ASC';

$stmt = $db->prepare("SELECT field from table WHERE column = :my_param ORDER BY :order :direction");
$stmt->bindParam(':my_param', $is_live, PDO::PARAM_STR);
$stmt->bindParam(':order', $order, PDO::PARAM_STR);
$stmt->bindParam(':direction', $direction, PDO::PARAM_STR);
$stmt->execute();

:my_param работает, но не :order или :direction. Правильно ли сбежал изнутри? Я застрял, вставив его непосредственно в SQL? Вот так:

$order = 'columnName';
$direction = 'ASC';

$stmt = $db->prepare("SELECT * from table WHERE column = :my_param ORDER BY $order $direction");

Есть ли PDO::PARAM_COLUMN_NAME константа или какой-то эквивалент?

Спасибо!

Ответы [ 8 ]

47 голосов
/ 30 марта 2010

Да, вы застряли, вставляя его прямо в SQL. С некоторыми мерами предосторожности, конечно. Каждый оператор / идентификатор должен быть жестко задан в вашем скрипте , например:

$orders=array("name","price","qty");
$key=array_search($_GET['sort'],$orders);
$order=$orders[$key];
$query="SELECT * from table WHERE is_live = :is_live ORDER BY $order";

То же самое для направления.

Обратите внимание, что bindParam не экранирует, поскольку экранирование не требуется. Это делает обязательным.

12 голосов
/ 30 марта 2010

Я не думаю, что вы можете:

  • Использовать заполнители в order by предложении
  • Привязка имен столбцов: вы можете связывать только значения - или переменные, и их значения вводятся в подготовленный оператор.
9 голосов
/ 14 октября 2015

Возможно использовать подготовленные операторы в предложении ORDER BY, к сожалению, вам нужно передать порядок вставленных столбцов в имени и установить PDO_PARAM_INT с типом.

В MySQL вы можете получить порядок столбцов с этим запросом:

SELECT column_name, ordinal_position FROM information_schema.columns 
WHERE table_name = 'table' and table_schema = 'database'

PHP код:

$order = 2;

$stmt = $db->prepare("SELECT field from table WHERE column = :param ORDER BY :order DESC");
$stmt->bindParam(':param', $is_live, PDO::PARAM_STR);
$stmt->bindParam(':order', $order, PDO::PARAM_INT);
$stmt->execute();
4 голосов
/ 30 марта 2010

Я не думаю, что вы можете получить ASC / DESC как часть подготовленного заявления, но столбец вы можете.

 order 
    by 
       case :order
           when 'colFoo' then colFoo
           when 'colBar' then colBar
           else colDefault
       end
       $direction

Поскольку ASC / DESC - это только два возможных значения, вы можете легко проверить и выбрать между ними как жестко заданные значения.

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

0 голосов
/ 30 октября 2015

Это возможно . Вы можете использовать число вместо имени поля в предложении 'order by'. Это число, начинающееся с 1 и имеющее порядок имен полей в запросе. И вы можете объединить строку для ASC или DESC. Например Msgstr "Выбрать col1, col2, col3 из табуляции в порядке?" + StrDesc + "предел 10,5". strDesc = "ASC" / "DESC".

0 голосов
/ 05 марта 2015

Создание условия if-else.
Если (ascCondion), то связать значения, но жесткий код ORDER BY columnName ASC
прочее
Привязать значения, но жесткий код ORDER BY COlumnName DESC

0 голосов
/ 04 июля 2012

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

Создайте запрос, используя стандартные escape-символы, и выполните его напрямую.

0 голосов
/ 30 марта 2010

Если я не совсем ошибаюсь, Паскаль прав.
Единственная возможная привязка в PDO - это привязка значений, как вы делали с параметром ': my_param'.
Тем не менее, нет никакого вреда в:

$stmt = $db->prepare("SELECT field from table WHERE column = :my_param ORDER BY ".$order ." ".$direction);
$stmt->bindParam(':my_param', $is_live, PDO::PARAM_STR);
$stmt->execute();

Единственное, на что стоит обратить внимание, это правильное экранирование $order и $direction, но, поскольку вы установили их вручную, а не установили их с помощью пользовательского ввода, я думаю, что все настроено. *

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