Подтвердить что ты не робот

Как установить параметры ORDER BY с помощью подготовленной инструкции PDO?

У меня возникают проблемы с использованием параметров в разделе 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 или какой-либо эквивалент?

Спасибо!

4b9b3361

Ответ 1

Да, вы застряли, вставив его прямо в 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 не может убежать, так как никакого побега не требуется. Это делает обязательным.

Ответ 2

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

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

Ответ 3

Возможно использование готовых операторов в 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

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

// Validate between 2 possible values:
$sortDir = isset($_GET['sortDir']) && $_GET['sortDir'] === 'ASC' ? 'ASC' : 'DESC';
$sql = "
...
     order 
        by 
           case :orderByCol
               when 'email' then email
               when 'age' then age
               else surname
           end
           $sortDir
";
$stmt = $db->prepare($sql);
$stmt->bindParam(':orderByCol', $someColumn);
$stmt->execute();

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

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

Ответ 5

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

Создайте запрос с помощью стандартных экранов и выполните его непосредственно.

Ответ 6

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

Ответ 7

Если я не ошибаюсь, Паскаль прав.
Единственное связывание, возможное в 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, но поскольку вы устанавливаете их вручную и не устанавливаете их через пользовательский ввод, я думаю, что вы все настроены.

Ответ 8

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