注意:这不是What is maximum query size for mysql?的副本。我的问题似乎是特定于Doctrine和/或PHP,而不是MySQL。
我的查询如下所示:
SELECT COUNT(*) FROM post
WHERE username = :username
AND comment REGEXP '...giant regular expression...'
请注意,巨大的正则表达式不包括文本:username
(这可能会混淆Doctrine)。
我的PHP是普通的Doctrine DQL,就像
$connection->executeQuery($sql, ['username' => 'Frank Sinatra']);
我得到PDO DriverException SQLSTATE[HY093]: Invalid parameter number: no parameters were bound
。实际上,我可以从错误输出中看到Doctrine没有尝试输入我告诉它的参数。
经过几个小时的调试,我终于发现这与查询本身的长度有某种关系。如果查询字符串大约为3,074个字符,它将运行正常。此外,此问题仅发生在准备好的语句中。如果我不需要绑定任何参数,那么非常长(超过3,074个字符)的查询可以正常工作。
为了让它更令人困惑,我只在我的本地环境(PHP 7.2)上出现此错误,而不是仍在PHP 5.6上的生产。我不知道PHP是否是问题,但我想不出任何其他的东西。我已经运行composer update
来获取PHP 7.2的最新版本的依赖项(Doctrine等)。
我不相信它是由于MySQL max_allowed_packet
选项的低值或MySQL中的任何其他因素,因为我可以在MySQL控制台中手动运行查询(输入参数值)并且它可以工作。所以,我要责怪Doctrine或PHP本身。
有谁听说过这个问题?在PHP或Doctrine中是否存在一些最大查询长度的秘密设置,这会导致Doctrine以这种方式混淆?
正则表达式是什么样的,你是如何产生它的?它有问号吗?如果是这样,它会期望您为这些参数绑定参数。
如果您还没有,那么您也应该绑定正则表达式值:
$sql = 'SELECT COUNT(*) FROM post WHERE username = :username AND comment REGEXP :comment_regex;';
$connection->executeQuery($sql, [
'username' => $username,
'comment_regex' => $comment_regex,
]);
旁注:我建议使用ids而不是用户名作为外键,以提高性能和实用性(如果您必须更改用户名,则无需乐趣)。