如何正确复用Doctrine自定义DQL函数参数避免绑定值缺失错误
解决Doctrine自定义DQL函数复用参数时的绑定错误
问题核心在于多次调用dispatch($sqlWalker)会重复生成参数占位符:当你在SQL模板中重复使用同一个参数时,每次调用$this->arg1->dispatch($sqlWalker)都会让Doctrine生成新的位置占位符(比如?1、?3),但你只绑定了一次:arg1,自然会触发参数绑定缺失的错误。
正确的做法是提前缓存参数的SQL解析结果,避免重复调用dispatch。修改你的getSql()方法如下:
public function getSql(SqlWalker $sqlWalker): string { // 先解析并缓存参数的SQL表示,避免重复生成占位符 $arg1Sql = $this->arg1->dispatch($sqlWalker); $arg2Sql = $this->arg2->dispatch($sqlWalker); $formula = '(%1$s + %2$s) * %1$s'; return \sprintf($formula, $arg1Sql, $arg2Sql); }
原理说明:
- 对于实体属性(比如
entity.property),dispatch()会生成对应的字段名,重复调用不会有问题; - 对于命名参数(比如
:arg1),dispatch()每次调用都会生成新的位置占位符,这会导致Doctrine期望你绑定更多参数,但实际你只提供了一次,从而触发Positional parameter at index XXX does not have a bound value错误; - 缓存
dispatch()的结果后,整个SQL模板中会复用同一个占位符,参数绑定就能正确匹配。
内容的提问来源于stack exchange,提问作者Marcin Orlowski
相关产品推荐
相关产品推荐

