2012-11-07 16 views
13

ottengo un errore di strano quando eseguo questa query DQL:Utilizzare una funzione DATE() in una clausola WHERE con DQL

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

L'eccezione viene generata da Doctrine con il messaggio:

Expected known function, got 'DATE' 

Il problema è simile a this bug, ma si riferisce alla funzione DATE() in una clausola GROUP BY e il bug è chiuso per Doctrine 2.2. In questo momento, ottengo l'eccezione con doctrine 2.4-DEV.

La query ha lo scopo di selezionare tutti gli utenti pianificati per oggi. C'è un modo per creare questo DQL? Ho testato la versione SQL in phpMyAdmin e lì la query non genera un errore. Cosa potrebbe essere sbagliato?

+1

Doctrine2 DQL non ha una funzione DATE() o NOW(): http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#dql-functions . Ma vuoi davvero confrontare due timestamp sulla loro uguaglianza? – memoryleak

+0

Ho programmato i pazienti per un appuntamento (data + ora) e voglio elencare tutti i pazienti per oggi. C'è un modo brutto per farlo: preparare la dichiarazione con un oggetto php 'DateTime' per" oggi ". E dividi il campo datetime in una parte "date" e "time". Posso superare la prima parte brutta, ma la seconda è solo un problema con il tuo db perché è un problema di livello di astrazione. Ecco perché ho sperato in una soluzione in cui ciò avrebbe funzionato :) Ho provato un 'SELECT CAST (s.timestamp come DATE) come schedule_day FROM ... WHERE schedule_day =: today' ma ha restituito un errore simile ... –

risposta

31

È possibile ottenere ciò che si desidera utilizzando un 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); 
    } 
} 

Poi la registrazione di questa funzione nel codice:

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

E la query DQL funzionerà!

+0

WIll prova, grazie! Questo potrebbe salvarmi un sacco di mal di testa in cui avrei diviso il timestamp pianificato in una parte separata di giorno e ora –

+0

Ha funzionato per me! T4All! –

+7

Ecco come registrare la nuova funzione DQL in un'app Symfony2: http://symfony.com/doc/current/cookbook/doctrine/custom_dql_functions.html – Quentin

Problemi correlati