22

我遇到了这个烦人的错误,尽管我知道为什么会遇到它,但我终其一生都无法找到解决方案。

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 错误,因此所有占位符都已正确绑定(我假设)。

询问:

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

所有占位符值都位于 $criteria 中,除了最后两个 LIMIT,我手动绑定了bindValue().

4

7 回答 7

30

当使用相同的参数名称绑定两个值时,可能会发出同样的错误 2031,例如:

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

..所以,小心。

于 2016-03-01T18:42:20.783 回答
27

您不能使用->bind* ->execute($params)。使用或;如果您将参数传递给execute(),那些将使 PDO 忘记已经通过绑定的参数->bind*

于 2013-06-24T11:58:40.103 回答
17

如果您尝试使用占位符运行查询而不是准备语句,也会出现此异常

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

代替

$stmt = $db->prepare('SELECT * FROM tbl WHERE ID > ?');
于 2016-10-10T20:03:42.487 回答
3

手册

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

执行准备好的语句。如果准备好的语句包含参数标记,您必须:

  • 调用 PDOStatement::bindParam() 将 PHP 变量绑定到参数标记:绑定变量将其值作为输入传递并接收其关联参数标记的输出值(如果有)

  • 或传递一个仅输入参数值的数组

你需要选择一种方法。你不能同时混合两者。

于 2013-06-24T11:59:00.933 回答
2

这不完全是一个答案,但是如果您尝试使用带有连字符的单词作为占位符,也会发生此错误,例如:

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

所以更好用

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

于 2017-01-03T18:03:36.557 回答
1

如果您的参数不匹配,就会发生这种情况。例如:

$q = $db->prepare("select :a, :b");
$q->execute([":a"=>"a"]);
于 2018-01-24T11:41:02.213 回答
0

当您的 SQL 尝试更新 AUTO_INCREMENT 字段时,也会发生异常(至少在 MySQL/PDO 中)。

于 2017-01-02T02:09:30.820 回答