如何在 Doctrine 2 DQL 中使用 DATE()?

Posted

技术标签:

【中文标题】如何在 Doctrine 2 DQL 中使用 DATE()?【英文标题】:How can I use DATE() in Doctrine 2 DQL? 【发布时间】:2014-09-17 06:21:56 【问题描述】:

在 Symfony 中,当我在 mysql 中使用带有 DATE 函数的以下查询时,我得到一个错误

    SELECT employer.companyName AS employerName, jobs.jobId, jobs.industryId, 
jobs.focusId, jobs.companyName, jobs.employerId, jobs.jobTitle, DATE(jobs.createdDate) AS 
createdDate , DATE(jobs.endDate) AS endDate , jobs.replyTo, jobs.featured , jobs.jobType, 
jobs.status  FROM Acme\\AppsBundle\\Entity\\Jobs jobs , Acme\\AppsBundle\\Entity\\Employer 
employer  WHERE  jobs.employerId = employer.employerId  GROUP BY  jobs.jobId  ORDER BY 
jobs.jobId DESC 

为什么会这样以及有什么样的解决方法来克服这种情况,在数据库中这些字段,即 end_date 被存储为 mysql type 'date'

    [2014-09-17 05:52:42] request.CRITICAL: Uncaught php Exception Doctrine\ORM\Query
\QueryException: "[Syntax Error] line 0, col 138: Error: Expected known function, got 
'DATE'" at /.../Doctrine/ORM/Query/QueryException.php line 52 "exception":"[object] 
(Doctrine\\ORM\\Query\\QueryException: [Syntax Error] line 0, col 138: Error: Expected known function, got 'DATE' at /var/w.../doctrine/orm/lib/Doctrine/ORM/Query
/QueryException.php:52, Doctrine\\ORM\\Query\\QueryException: SELECT employer.companyName 
AS employerName, jobs.jobId, jobs.industryId, jobs.focusId, jobs.companyName, jobs.employerId, jobs.jobTitle, DATE(jobs.createdDate) AS createdDate , DATE(jobs.endDate) 
AS endDate , jobs.replyTo, jobs.featured , jobs.jobType, jobs.status  FROM Acme\\AppsBundle
\\Entity\\Jobs jobs , Acme\\AppsBundle\\Entity\\Employer employer  WHERE  jobs.employerId 
= employer.employerId  GROUP BY  jobs.jobId  ORDER BY  jobs.jobId DESC  at /var/w...
/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php:41)" []

【问题讨论】:

【参考方案1】:

除了接受的答案之外,https://github.com/beberlei/DoctrineExtensions 上还有大量预构建的自定义函数。

这些可以像这样在你的配置中注册

doctrine:
    orm:
        dql:
            string_functions:
                DATE: DoctrineExtensions\Query\Mysql\Date

然后可以在您的 DQL(如您的查询)中使用,例如

DATE(jobs.endDate) AS endDate

【讨论】:

如果这对任何人都不起作用(如果它引发 dql 无法识别的错误),当我将 entity_managers: default: 放在 dql 之前的层次结构中时,它可以工作。 这取决于您的配置。 doctrine.orm.dqldoctrine.orm.entity_managers.default.dql 的缩写。您之前是否在配置中的其他地方提到了 entity_managers? 是的entity_managers 在我的config.yml 中已经低于orm,所以我认为这是doctrine.orm.dql 不起作用但doctrine.orm.dql 起作用的原因。很高兴知道。【参考方案2】:

或者如果你不想添加新的依赖,你可以使用这样的代码:

$dateTime = new \DateTime();
$qb
   ->andWhere('jobs.endDate BETWEEN :dateMin AND :dateMax')
   ->setParameters(
       [
            'dateMin' => $dateTime->format('Y-m-d 00:00:00'),
            'dateMax' => $dateTime->format('Y-m-d 23:59:59'),
       ]
    );

【讨论】:

【参考方案3】:

DQL 只知道几个标准的 sql 函数(例如coalesce)。为了能够使用您的自定义函数,您需要注册它并告诉doctrine 如何将其转换为原始 sql。请遵循以下指南:

Symfony Doc

Doctrine Doc

并检查我的答案here

【讨论】:

以上是关于如何在 Doctrine 2 DQL 中使用 DATE()?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 的 Doctrine 2 中更改 DQL 查询中的 LockMode

DQL 语句在使用 Zend Framework 和 Doctrine 的应用程序中的位置

Doctrine DQL:如何使表达式反转

如何删除学说 Doctrine Raw Sql 查询中的特定 dql 部分?

带有类名的 Doctrine 2 DQL 查询?

Doctrine 2 DQL CONCAT 字段和常量字符串