Как использовать подготовленный оператор pdo для порядка и ограничений?

Я хочу использовать подготовленный оператор, в котором параметры передаются для предложений ORDER BY и LIMIT , например:

 $sql = 'SELECT * FROM table ORDER BY :sort :dir LIMIT :start, :results'; $stmt = $dbh->prepare($sql); $stmt->execute(array( 'sort' => $_GET['sort'], 'dir' => $_GET['dir'], 'start' => $_GET['start'], 'results' => $_GET['results'], ) ); 

Но $stmt->fetchAll(PDO::FETCH_ASSOC); ничего не возвращает.

Может кто-то указать, что я делаю не так? Это можно сделать? Если нет, что я должен ссылаться на полный список предложений, в которых могут использоваться параметры?

Solutions Collecting From Web of "Как использовать подготовленный оператор pdo для порядка и ограничений?"

После использования:

 $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

Я получил сообщение:

Исключить исключение «PDOException» с сообщением «SQLSTATE [42000]: Ошибка синтаксиса или нарушение доступа: 1064 У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с '0', '10' 'в строке 1

Итак, когда вы используете массив для выполнения, он рассматривает ваши входы как строку, которая не является хорошей идеей для LIMIT

 $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "SELECT * FROM table ORDER BY :sort :dir LIMIT :start, :results"; $stmt = $dbh->prepare($sql); $stmt->bindParam(':start', $_GET['start'], PDO::PARAM_INT); $stmt->bindParam(':results', $_GET['results'], PDO::PARAM_INT); $stmt->bindParam(':sort', $_GET['sort']); $stmt->bindParam(':dir', $_GET['dir']); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); print_r($data); 

Подготовленные утверждения позволяют СУБД генерировать план запроса для вашего запроса до фактического выполнения запроса для ваших параметров. Изменение полей для ORDER BY требует другого плана запроса, поскольку упорядочение данных различными способами может существенно повлиять на то, как СУБД может выбрать получение данных: например, некоторые индексы могут помочь в одном случае, но не в другом. По этой причине поля ORDER BY должны быть частью строки SQL, переданной в метод prepare() , а не привязываться к запросу до execute() .

Что касается предложения LIMIT , неясно, повлияют ли его параметры на план запроса, поэтому они могут быть связаны позже, возможно, в зависимости от вашей СУБД. Согласно этому ответу SO, это должно быть разрешено.

Вы не можете привязать параметр, чтобы указать ключевое слово языка или имя поля – он должен быть заменен литералом. Поэтому ваши предельные значения, на мой взгляд, прекрасны, но ваш заказ – нет. Лучше всего будет вручную заменить sort и dir в строке. Побег их, но не используйте инструменты БД для этого, так как они не являются строковыми литералами. В принципе, никаких специальных символов не существует.

Хотя этот вопрос довольно старый, я думаю, что это все равно может представлять интерес. Для меня это сработало после того, как я

  1. использовал bindParam в сочетании с PDO::PARAM_INT как это было предложено ранее
  2. преобразует содержимое переменной в целочисленное значение, вызывая intval()

Соответствующая часть кода выглядит следующим образом:

  $stmt->bindParam(':start', intval($_GET['start']), PDO::PARAM_INT); $stmt->bindParam(':number', intval($_GET['number']), PDO::PARAM_INT); 

Без использования intval() я также получил ошибку Синтаксическая ошибка или нарушение прав доступа: 1064 У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования около '' 0 ', 10' в строке 1