【问题标题】:Large query with bound parameters causes invalid parameter number error in Doctrine带有绑定参数的大型查询导致Doctrine中的参数号无效错误
【发布时间】:2018-09-13 03:46:40
【问题描述】:

注意:这不是 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 以这种方式混淆?

【问题讨论】:

    标签: php doctrine-orm doctrine doctrine-query


    【解决方案1】:

    正则表达式是什么样的,您是如何生成它的?它有问号吗?如果是这样,它将期望您为这些绑定参数。

    如果您还没有,您也应该绑定正则表达式值:

    $sql = 'SELECT COUNT(*) FROM post WHERE username = :username AND comment REGEXP :comment_regex;';
    
    $connection->executeQuery($sql, [
        'username'      => $username,
        'comment_regex' => $comment_regex,
    ]);
    

    附注:为了性能和实用性,我建议使用 ids 而不是用户名作为外键(如果你必须更改用户名,那就不好玩了)。

    【讨论】:

    • 抱歉回复晚了。 “如果你还没有,你也应该绑定正则表达式值”——做到了!!!问题是,这在之前运行良好(完全相同的正则表达式),但在 PHP 7.2 或某些 Doctrine 更新中中断。无论如何,绑定正则表达式似乎更干净。谢谢你。帖子/用户名/评论只是一个例子。我的架构实际上并不像这样 :) 再次感谢。
    猜你喜欢
    • 2021-01-09
    • 1970-01-01
    • 2016-01-11
    • 2019-01-10
    • 2012-03-10
    • 2012-09-05
    • 2019-02-18
    • 1970-01-01
    • 2017-01-31
    相关资源
    最近更新 更多