PDO 错误:SQLSTATE [HY000]:一般错误:2031

Posted

技术标签:

【中文标题】PDO 错误:SQLSTATE [HY000]:一般错误:2031【英文标题】:PDO error: SQLSTATE[HY000]: General error: 2031 【发布时间】:2013-06-20 21:44:03 【问题描述】:

我遇到了这个烦人的错误,虽然我知道为什么会遇到这个错误,但我终其一生都找不到解决办法。

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

【问题讨论】:

尝试在google中搜索“PDO绑定LIMIT参数” 1) 最好包含人类可读的错误消息,而不仅仅是神秘代码,2) 显示您的实际查询,以便我们查看错误的根源。 @deceze 如果那里有任何人类可读的消息,我会:a)现在可能已经解决了,b)如果没有,那么把它包括在这里。这是完整的错误消息,相信我。 错误:2031 (CR_PARAMS_NOT_BOUND)消息:没有为准备好的语句中的参数提供数据来自文档dev.mysql.com/doc/refman/5.0/en/error-messages-client.html 您确定要绑定:strength 吗?确定$limit 是真的吗? 【参考方案1】:

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

【讨论】:

【参考方案2】:

来自the manual:

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

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

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

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

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

【讨论】:

我不能将bindParam/bindValue 用于其他值...叹息。 @silkfire 其他想法请见***.com/questions/10014147/…。 PDO::ATTR_EMULATE_PREPARES, true) - enable 不应该模拟准备吗?我认为这是相反的方式,非常具有误导性。 @silkfire - 这是为了发现错字,我刚刚改正了。【参考方案3】:

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

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

..所以,小心。

【讨论】:

这个答案拯救了我的一天! 你拯救了我的一天。我将参数名称更改为.. ':colour0', 'colour1', 'colour2' ... 。问题就解决了。【参考方案4】:

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

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

而不是

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

【讨论】:

你节省了我的时间!【参考方案5】:

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

【讨论】:

我不知道为什么有人反对 Roadowl 的回答。该错误的实际情况是它非常笼统。【参考方案6】:

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

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

所以更好用

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

【讨论】:

【参考方案7】:

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

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

【讨论】:

以上是关于PDO 错误:SQLSTATE [HY000]:一般错误:2031的主要内容,如果未能解决你的问题,请参考以下文章

使用 PDO 连接到远程 MYSQL 服务器,导致相同的错误 SQLSTATE[HY000] [2002] [重复]

PHP/PDO 错误:SQLSTATE[HY000] 无法连接:Adaptive Server 不可用或不存在(严重性 9)

SQLSTATE[HY000] [2002] 资源暂时不可用 - mysql - innodb 和 pdo

什么会导致间歇性 SQLSTATE[HY000] [2002] Debian Lenny 上的 php PDO mysql 没有此类文件或目录错误? [复制]

SQLSTATE[HY000] [2002] 操作超时

SQLSTATE[HY000] [2002] 权限被拒绝 Laravel PDO 驱动程序(凭证通过工匠迁移工作)