Ключевое слово LIMIT для MySQL с подготовленным оператором

SELECT id, content, date
FROM comment
WHERE post = ?
ORDER BY date DESC
LIMIT ?, ?

С PDO (я использую MAMP 2.0.5 с Apache 2.2.21, PHP до 5.3.6 и MySQL 5.5.9), подготовленный оператор не работает, если я изменяю запрос с помощью

LIMIT 0, 10

он работает.

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

Если это все еще проблема, есть способ выбрать диапазон строк по-другому?

код:

$comments = $db->prepare($query); 
/* where $db is the PDO object */ 
$comments->execute(array($post, $min, $max)); 

Ответы

Ответ 1

Здесь проблема:

$comments = $db->prepare($query); 
/* where $db is the PDO object */ 
$comments->execute(array($post, $min, $max));

Страница руководства для PDOStatement:: execute() говорит (основное внимание):

Параметры

input_parameters Массив значений с таким количеством элементов, как есть связанных параметров в выполняемом операторе SQL. Все значения обрабатывается как PDO:: PARAM_STR.

Таким образом, ваши параметры вставляются в виде строк, поэтому последний код SQL выглядит следующим образом:

LIMIT '0', '10'

Это частный случай, когда MySQL не будет приводить число, но вызывает ошибку синтаксического анализа:

mysql> SELECT 1 LIMIT 0, 10;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

mysql> SELECT 1 LIMIT '0', '10';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''0', '10'' at line 1

Что docs должны сказать:

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

  • В рамках подготовленных операторов параметры LIMIT можно указать с помощью? маркеры заметок.

  • Внутри сохраненных программ параметры LIMIT могут быть заданы с использованием параметров с использованием целочисленных параметров или локальных переменных.

Ваш выбор включает:

  • Свяжите параметры по одному, чтобы вы могли установить тип:

    $comments->bindParam(1, $post, PDO::PARAM_STR);
    $comments->bindParam(2, $min, PDO::PARAM_INT);
    $comments->bindParam(3, $min, PDO::PARAM_INT);
    
  • Не передавайте эти значения в качестве параметров:

    $query = sprintf('SELECT id, content, date
        FROM comment
        WHERE post = ?
        ORDER BY date DESC
        LIMIT %d, %d', $min, $max);
    
  • Отключить эмулированные подготавливает (у драйвера MySQL есть ошибка/функция, которая заставит его процитировать числовые аргументы):

    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
    

Ответ 2

$dbh->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );

решит эту проблему.