2012-11-07 10 views
13

mam dziwny błąd podczas wykonywania tej kwerendy DQL:Użyj funkcji Date() w klauzuli WHERE z DQL

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

Wyjątkiem jest wyrzucane przez Doctrine z komunikatem:

Expected known function, got 'DATE' 

Problem wygląda podobnie do this bug, ale dotyczy funkcji DATE() w klauzuli GROUP BY, a błąd jest zamknięty dla Doctrine 2.2. W tej chwili otrzymuję wyjątek z doktryną 2.4-DEV.

Zapytanie ma na celu wybranie wszystkich użytkowników zaplanowanych na dziś. Czy istnieje sposób, w jaki mogę stworzyć ten DQL? Przetestowałem wersję SQL w phpMyAdmin i tam zapytanie nie wywołuje błędu. Co może być nie tak?

+1

Doctrine2 DQL nie ma funkcji DATE() ani NOW(): http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#dql-functions . Ale czy naprawdę chcesz porównać dwa znaczniki czasu dotyczące ich równości? – memoryleak

+0

Mam zaplanowanych pacjentów na spotkanie (data + czas) i chcę listę wszystkich pacjentów na dziś. Istnieje brzydki sposób, aby to zrobić: przygotuj instrukcję z obiektem 'DateTime' dla" dzisiaj ". I podziel pole datetime na część "date" i "time". Mogę przezwyciężyć pierwszą brzydką część, ale drugą jest po prostu wkręcanie z twoją db, ponieważ problem z warstwą abstrakcji. Dlatego właśnie liczyłem na rozwiązanie, w którym to mogłoby działać :) Próbowałem 'SELECT CAST (s.timestamp jako DATE) jako schedule_day FROM ... WHERE schedule_day =: today' ale zwrócił podobny błąd ... –

Odpowiedz

31

Można osiągnąć to, co chcesz za pomocą 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); 
    } 
} 

Następnie rejestracji tej funkcji w kodzie:

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

I zapytanie DQL zadziała!

+0

WIll spróbuj, dzięki! To może zaoszczędzić mi wielu bólów głowy, w których podzieliłbym zaplanowany znacznik czasu w oddzielnym dniu i czasie część –

+0

To działało dla mnie! T4All! –

+7

Oto jak zarejestrować nową funkcję DQL w aplikacji Symfony2: http://symfony.com/doc/current/cookbook/doctrine/custom_dql_functions.html – Quentin

Powiązane problemy