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

Как использовать подготовленную инструкцию 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); ничего не возвращает.

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

4b9b3361

Ответ 1

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

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

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

Отключить исключение "PDOException" с помощью message '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);

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

  • используется bindParam в сочетании с PDO::PARAM_INT, как предлагается до
  • преобразовал содержимое переменной в целочисленное значение, вызвав 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