2014-09-23 6 views
7

Ich muss alle Zeilen erhalten, in denen DATE(a.when) die Zeichenfolge 2014-09-30 entspricht.Verwenden von `DATE()` in Doctrine QueryBuilder

$builder = $this->em->createQueryBuilder(); 
$builder->select('a') 
     ->from('Entity\Appointment', 'a') 
     ->andWhere('a.when = :date') 
     ->setParameter('date', $date); 

a.when ist ein voll DATETIME; :date ist nur ein string (in DATE Format).

Folge- und Variationen hat nicht funktioniert:

 ->andWhere('DATE(a.when) = :date') 

Error: Expected known function, got 'DATE' 

Was ist die korrekte Verwendung hier?

+0

möglich Duplikat [Lehre 2 - Ergebnis durch ein Datum Teil des Datetime-Feldes] (http://stackoverflow.com/questions/10824383/doctrine-2 -filter-result-by-a-datetime-felder-date-part) – andy

+0

@andy kein Duplikat. Ich benutze den ** queryBuilder ** und die Fehlermeldung mit 'createQuery' und der' queryBuilder' ist gleich: 'Error: Erwartete bekannte Funktion, habe 'DATE' bekommen. – DanFromGermany

+1

Der Fehler ist derselbe, weil in DQL kein 'DATE()' vorhanden ist. Wenn Sie die WHERE-Klausel aus dem verknüpften Duplikat verwenden, sollte Ihr Ansatz ebenfalls funktionieren. – andy

Antwort

7

Das ist eigentlich eine sehr häufige Frage. Es stellt sich heraus, dass nicht alle SQL-Datenbanken eine DATE-Funktion unterstützen, so dass die guten Leute, die für Doctrine zuständig sind, entschieden haben, sie nicht nativ zu unterstützen.

Eine Art von Wunsch, den sie getan haben, weil es eine Menge Leute eine ziemlich Menge Mühe gespart hätte.

So fügen Sie diese eher magische Klasse zum Projekt hinzu:

doctrine: 
    orm: 
    default_entity_manager:  default 
    auto_generate_proxy_classes: %kernel.debug% 

    entity_managers: 

    default: 
     connection: default 
     ... 
     dql: 
     datetime_functions: 
      date: Cerad\Bundle\CoreBundle\Doctrine\DQL\Date 

http://doctrine-orm.readthedocs.org/en/latest/cookbook/dql-user-defined-functions.html http://symfony.com/doc/current/cookbook/doctrine/custom_dql_functions.html http://symfony.com/doc/current/reference/configuration/doctrine.html

:

namespace Cerad\Bundle\CoreBundle\Doctrine\DQL; 

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

class Date extends FunctionNode 
{ 
    public $date; 

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) 
    { 
     return "DATE(" . $sqlWalker->walkArithmeticPrimary($this->date) . ")"; 
    } 
    public function parse(\Doctrine\ORM\Query\Parser $parser) 
    { 
     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 

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

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

es dann in der Lehre Abschnitt Ihrer app/config.yml verdrahten

Es gibt andere Bündel mit mehr SQL-Funktionen. Seltsamerweise, als ich das erste Mal vor ein paar Jahren aussah, hatte keiner von ihnen Date definiert. Also habe ich einfach mein eigenes gemacht.

============================================== ======================

aktualisieren 01

ich nicht überprüfen Sie die Tags sorgfältig und angenommen, dass dies ein Symfony 2-Anwendung war. Die Date-Klasse bleibt gleich. Sie verbinden es, indem Sie das Doktrin-Konfigurationsobjekt erhalten.

$config = new \Doctrine\ORM\Configuration(); 
$config->addCustomDatetimeFunction('DATE', 'blahblah\Date'); 

Weitere Informationen finden Sie im Doctrine-Link.

+0

Ich gebe Ihnen eine Anregung für Ihre Bemühungen, leider kann ich nicht unsere Kernbibliotheken wie Doctrine ändern. Ich gehe jetzt mit einem Nicht-DQL-Weg, bis ich einen besseren Weg finde. – DanFromGermany

+0

Sie ändern die Kernbibliothek nicht. Sie fügen nur eine benutzerdefinierte Funktion hinzu. Nichts in Doctrine wird verändert. – Cerad

+0

Ich kann es nicht "verdrahtet" bekommen. Ich habe diese Konfigurationsdatei nicht.Ich habe jetzt mit 'YEAR()', 'DAY()' und 'MONTH()' versucht, weil ihre Klassendateien schon da waren, aber der Fehler ist dementsprechend der gleiche .. – DanFromGermany

7

Dank andy, das jetzt mit:

$builder = $this->em->createQueryBuilder(); 
$builder->select('a') 
     ->from('Entity\Appointment', 'a') 
     ->andWhere('a.when > :date_start') 
     ->andWhere('a.when < :date_end') 
     ->setParameter('date_start', $date->format('Y-m-d 00:00:00')) 
     ->setParameter('date_end', $date->format('Y-m-d 23:59:59'));