2012-11-07 49 views
13

我得到一个奇怪的错误,当我执行此DQL查询:使用日期()函数在WHERE子句中使用DQL

SELECT u FROM User u LEFT JOIN u.schedule s WHERE DATE(s.timestamp) = DATE(NOW()) 

异常是由主义与消息抛出:

Expected known function, got 'DATE' 

该问题看起来与this bug类似,但是它解决了GROUP BY子句中的DATE()函数,并且该错误对于Doctrine 2.2是关闭的。在这一刻,我发现了2.4-DEV教条的例外。

该查询旨在选择今天计划的所有用户。有没有什么办法可以创建这个DQL?我在phpMyAdmin中测试了SQL版本,在那里查询不会引发错误。什么可能是错的?

+1

Doctrine2 DQL没有DATE()或NOW()函数:http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#dql-functions 。但是你真的想比较两个时间戳的平等吗? – memoryleak

+0

我已安排病人预约(日期+时间),我想列出今天的所有病人。有一个丑陋的方式来做到这一点:准备语句与“日期时间”对象为“今天”。并将日期时间字段拆分为“日期”和“时间”部分。我可以克服第一个丑陋的部分,但第二个只是因为抽象层问题而搞砸你的数据库。所以这就是为什么我希望解决方案,这将工作:)我尝试了'SELECT CAST(s.timestamp作为日期)作为schedule_day从... WHERE schedule_day =:今天',但它返回了类似的错误... –

回答

31

你可以实现你想要的使用custom function

use Doctrine\ORM\Query\AST\Functions\FunctionNode; 
use Doctrine\ORM\Query\Lexer; 
use Doctrine\ORM\Query\SqlWalker; 
use Doctrine\ORM\Query\Parser; 

class DateFunction extends FunctionNode 
{ 
    private $arg; 

    public function getSql(SqlWalker $sqlWalker) 
    { 
     return sprintf('DATE(%s)', $this->arg->dispatch($sqlWalker)); 
    } 

    public function parse(Parser $parser) 
    { 
     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 

     $this->arg = $parser->ArithmeticPrimary(); 

     $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
    } 
} 

然后注册该功能在你的代码:

$em->getConfiguration()->addCustomDatetimeFunction('DATE', 'DateFunction'); 

而且你的DQL的查询将工作!

+0

WIll试试,谢谢!这可以节省我很多头痛的地方,我将分开的日期和时间分开预定的时间戳 –

+0

它对我很有用! T4All! –

+7

以下是如何在Symfony2应用程序中注册新的DQL函数:http://symfony.com/doc/current/cookbook/doctrine/custom_dql_functions.html – Quentin