Ошибка PDO: SQLSTATE [HY000]: Общая ошибка: 2031

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

if ($limit) {
   $sth->bindValue(':page', $page - 1, PDO::PARAM_INT);
   $sth->bindValue(':entries_per_page', $page * $entries_per_page, PDO::PARAM_INT);
}

$sth->execute($criteria);

Запрос содержит заполнители (:placeholder). Но чтобы добавить те LIMIT-заполнители, мне нужно использовать ручной метод (bindValue), потому что иначе он превратит их в строки.

Я не получаю ошибку Invalid number of parameters, поэтому все заполнители были связаны правильно (я предполагаю).

Query:

SELECT `articles`.*, `regional_municipalities`.`name` AS `regional_municipality_name`, 
       `_atc_codes`.`code` AS `atc_code`, `_atc_codes`.`name` AS `substance`
FROM `articles`
LEFT JOIN `_atc_codes`
ON (`_atc_codes`.`id` = `articles`.`atc_code`)
JOIN `regional_municipalities`
ON (`regional_municipalities`.`id` = `articles`.`regional_municipality`)
WHERE TRUE AND `articles`.`strength` = :strength
GROUP BY `articles`.`id`
ORDER BY `articles`.`id`
LIMIT :page, :entries_per_page

Все значения заполнителя находятся в $критериях, за исключением последних двух LIMIT, которые я связываю вручную с помощью bindValue().

Ответы

Ответ 1

Вы не можете использовать ->bind* и ->execute($params). Используйте либо или; если вы передадите параметры на execute(), это заставит PDO забыть параметры, уже связанные с помощью ->bind*.

Ответ 2

Эта же ошибка 2031 может быть выдана, когда одна связывает два значения с тем же именем параметра, что и в:

  • $sth->bindValue(':colour', 'blue');
  • $sth->bindValue(':colour', 'red');

.. так что будьте осторожны.

Ответ 3

Это исключение также появляется, если вы пытаетесь выполнить запрос с заполнителями вместо подготовки отчета, такого как

$stmt = $db->query('SELECT * FROM tbl WHERE ID > ?');

вместо

$stmt = $db->prepare('SELECT * FROM tbl WHERE ID > ?');

Ответ 4

Из руководство:

public bool PDOStatement::execute ([ array $input_parameters ] )

Выполните подготовленный оператор. Если подготовленное выражение включено маркеров параметров, вы должны либо:

  • вызвать PDOStatement:: bindParam() для привязки переменных PHP к маркерам параметров: связанные переменные передают их значение как входные и получать выходное значение, если таковое имеется, связанного с ним параметра маркеры

  • или передать массив значений параметров только для ввода

Вам нужно выбрать метод. Вы не можете смешивать оба.

Ответ 5

Это не совсем ответ, но эта ошибка также возникает, если вы пытаетесь использовать слово с дефисом в качестве заполнителей, например:

$sth->bindValue(':page-1', $page1);

Поэтому лучше использовать

$sth->bindValue(':page_1', $page1);

Ответ 6

Это происходит, если у вас есть несоответствующие параметры. Например:

$q = $db->prepare("select :a, :b");
$q->execute([":a"=>"a"]);

Ответ 7

Исключение также происходит (по крайней мере, в MySQL/PDO), когда ваш SQL пытается ОБНОВИТЬ поле AUTO_INCREMENT.