在Doctrine ORM表达式构建器中使用REGEX() DQL函数遇PostgreSQL报错
问题描述
我已在Doctrine ORM中注册了REGEX() DQL函数,尝试通过表达式构建器使用该函数,代码如下:
$expr = $queryBuilder->expr(); $or = $expr->orX(); $or->add($expr->eq("REGEX(s.field, '[a-z]+')", true));
但代码无法正常运行,生成的SQL为s0_.field :: TEXT ~ '[a-z]' = 1,在PostgreSQL中抛出错误:
SQLSTATE[42883]: Undefined function: 7 ERROR: operator does not exist: boolean = integer.
尝试直接使用PostgreSQL的~运算符($or->add("s.field ~ '[a-z]+'")),但ORM不支持该运算符。
我的DQL函数getSql实现如下:
public function getSql(SqlWalker $sqlWalker): string { return sprintf( '%s :: TEXT %s %s', $this->fieldExpression->dispatch($sqlWalker), '~', $this->patternExpression->dispatch($sqlWalker), ); }
解决方案
方案1:直接将REGEX函数作为条件使用
无需用expr->eq()包裹,通过表达式构建器的func()方法调用自定义函数,直接将其作为布尔条件加入orX:
$expr = $queryBuilder->expr(); $or = $expr->orX(); // 使用func方法调用REGEX函数,直接作为条件 $or->add($expr->func('REGEX', 's.field', '[a-z]+'));
生成的SQL会是s0_.field :: TEXT ~ '[a-z]+',直接作为布尔判断条件,避免了布尔值与整数的比较。
方案2:调整DQL函数的SQL生成逻辑(可选)
如果需要保留eq(true)的写法,可修改getSql方法,将布尔结果转为整数适配比较逻辑:
public function getSql(SqlWalker $sqlWalker): string { return sprintf( '(%s :: TEXT %s %s)::INT', $this->fieldExpression->dispatch($sqlWalker), '~', $this->patternExpression->dispatch($sqlWalker), ); }
生成的SQL会是(s0_.field :: TEXT ~ '[a-z]+')::INT = 1,PostgreSQL会将布尔值转为整数(true=1,false=0),从而避免运算符错误。
内容的提问来源于stack exchange,提问作者simPod
相关产品推荐
相关产品推荐

