带有绑定参数的大型查询会导致Doctrine中的参数编号错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带有绑定参数的大型查询会导致Doctrine中的参数编号错误相关的知识,希望对你有一定的参考价值。

注意:这不是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而不是用户名作为外键,以提高性能和实用性(如果您必须更改用户名,则无需乐趣)。

以上是关于带有绑定参数的大型查询会导致Doctrine中的参数编号错误的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine DBAL - 带有附加参数的 WHERE IN 数组

这会导致集合中的两个绑定绑定到同一个属性。参数名称:c#中的绑定错误?

Doctrine Querybuilder,绑定参数

Doctrine2更新导致Zend Framework 3中的AnnotationRegistry registerLoader错误

有人可以建议一种使用带有多个“where”子句的 Doctrine (QueryBuilder) 进行此查询的方法吗?

将 Doctrine 的 EntityRepository::matching() 方法与 Criteria 对象一起使用时,如何绑定参数?