PDO错误:SQLSTATE [HY000]:常规错误:2031

时间:2013-06-24 11:38:21

标签: php mysql pdo prepared-statement

我收到了这个恼人的错误,虽然我知道为什么我会得到它,但我不能为我的生活找到解决方案。

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),否则引擎会将它们变成字符串。

我没有得到无效的参数数量错误,因此所有占位符都已正确绑定(我假设)。

查询:

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()

7 个答案:

答案 0 :(得分:22)

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

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

..所以,要小心。

答案 1 :(得分:19)

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

答案 2 :(得分:5)

如果您尝试使用占位符运行查询而不是准备诸如

之类的语句,则也会出现此异常
$stmt = $db->query('SELECT * FROM tbl WHERE ID > ?');

而不是

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

答案 3 :(得分:3)

来自the manual

  

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

     

执行准备好的声明。如果包括准备好的声明   参数标记,您必须

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

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

  •   

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

答案 4 :(得分:2)

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

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

更好用

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:-1)

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