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

Symfony3.4执行DQL查询时报错Expected known function, got 'CURDATE'如何解决?

问题产生原因
  • DQL是Doctrine提供的数据库抽象层查询语言,默认仅支持SQL标准定义的通用函数,代码中用到的CURDATE()、DATE_SUB()属于MySQL专属函数,未被Doctrine默认支持,因此解析DQL时会抛出函数未定义的语法错误。
  • 原生SQL可以正常运行,是因为原生SQL直接提交到MySQL解析执行,不需要经过Doctrine的DQL解析层。
解决方案

方案1:使用PHP计算日期参数传入DQL(最推荐,无需额外配置)

该方案避免在DQL中使用数据库专属函数,兼容性最强,修改后的代码如下:

public function get5DaysOldNotFilledQuestionnaires(){
    // 提前在PHP中计算出时间区间
    $startDate = new \DateTime('-5 days');
    $startDate->setTime(0,0,0);
    $endDate = new \DateTime('-4 days');
    $endDate->setTime(23,59,59);

    $raw_query = 'SELECT u.email, u.created 
    FROM  AppBundle:Questionnaire AS q 
    JOIN AppBundle:User AS u 
    WHERE u.is_api_user = 1 
    AND q.weight IS NULL
    AND u.created BETWEEN :start AND :end';

    $query = $this->getEntityManager()->createQuery($raw_query)
        ->setParameter('start', $startDate)
        ->setParameter('end', $endDate);
    $emails_to_remind = $query->getResult();

    return $emails_to_remind;
}

方案2:注册MySQL专属函数到Doctrine

如果需要在DQL中频繁使用MySQL函数,可以通过扩展包注册对应函数:

  1. 安装Doctrine扩展包:composer require beberlei/doctrineextensions
  2. 在Symfony3.4的app/config/config.yml中添加配置:
doctrine:
    orm:
        entity_managers:
            default:
                dql:
                    datetime_functions:
                        CURDATE: DoctrineExtensions\Query\Mysql\Curdate
                        DATE_SUB: DoctrineExtensions\Query\Mysql\DateSub

配置完成后原有DQL即可正常执行。

方案3:直接执行原生SQL

如果不想调整原有SQL逻辑,可以直接跳过DQL解析层执行原生SQL:

public function get5DaysOldNotFilledQuestionnaires(){
    $conn = $this->getEntityManager()->getConnection();
    $raw_query = 'SELECT u.email, u.created 
    FROM  questionnaire AS q 
    JOIN user AS u ON u.id = q.user_id
    WHERE u.is_api_user = 1 
    AND q.weight IS NULL
    AND u.created between DATE_SUB(CURDATE(), INTERVAL 5 DAY) AND DATE_SUB(CURDATE(), INTERVAL 4 DAY)';
    
    $stmt = $conn->executeQuery($raw_query);
    return $stmt->fetchAllAssociative();
}

注意原生SQL需要填写实际的表名和关联条件,不能使用实体别名。

内容的提问来源于stack exchange,提问作者user17027205

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 22:39:02