Doctrine QueryBuilder比较当前日期与存储日期时出现语法错误
解决Doctrine QueryBuilder中now()函数语法错误问题
需求
查询满足以下任一条件的数据行:
active字段为true- 当前日期处于
activationDate和deactivationDate之间
原错误代码
$qb->andWhere('p.active = true')') ->orWhere($qb->expr()->andX( $qb->expr()->lt('p.activationDate', 'now()'), $qb->expr()->eq('p.deactivationDate', 'now()') )) ->setMaxResults(1);
报错信息
[Syntax Error] line 0, col 145: Error: Expected known function, got 'now'
问题原因
Doctrine ORM的QueryBuilder不直接支持原生SQL的now()函数,必须使用其内置的日期函数或通过参数绑定PHP生成的当前时间。此外原代码存在两处问题:
- 第一行多了一个冗余的闭合单引号
') orWhere内的逻辑不符合"当前日期处于两个日期之间"的需求(原代码判断的是activationDate < now()且deactivationDate = now())
修复方案
方案一:使用Doctrine内置的CURRENT_TIMESTAMP()函数
Doctrine默认支持该函数,可直接替代now():
$qb->andWhere('p.active = true') ->orWhere($qb->expr()->andX( // 当前时间 >= activationDate $qb->expr()->lte('p.activationDate', 'CURRENT_TIMESTAMP()'), // 当前时间 <= deactivationDate $qb->expr()->gte('p.deactivationDate', 'CURRENT_TIMESTAMP()') )) ->setMaxResults(1);
方案二:绑定PHP当前时间作为参数(推荐,避免数据库函数差异)
通过参数绑定传递PHP生成的当前时间,兼容性更好:
$now = new \DateTime(); $qb->andWhere('p.active = true') ->orWhere($qb->expr()->andX( $qb->expr()->lte('p.activationDate', ':now'), $qb->expr()->gte('p.deactivationDate', ':now') )) ->setParameter('now', $now) ->setMaxResults(1);
注意事项
- 根据实际业务需求调整比较运算符:若需要严格处于两个日期之间(不包含边界),将
lte/gte替换为lt/gt - 确保实体类中
activationDate和deactivationDate字段的类型为日期时间类型(如DateTime)
内容的提问来源于stack exchange,提问作者fg_st
相关产品推荐
相关产品推荐

