You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:32:42