2013-09-30 7 views
11

Io uso Symfony 2 e la Doctrina ORM. Voglio creare e registrare una funzione DQL personalizzata. In realtà, io voglio usare la funzione SQL "CAST" nella mia richiesta, in questo modo:Errore quando si usa la funzione DQL personalizzata con Doctrine e Symfony2

$qb = $this->_em->createQueryBuilder(); 
    $qb->select('d') 
     ->from('\Test\MyBundle\Entity\MyEntity', 'd') 
     ->orderBy('CAST(d.myField AS UNSIGNED)', 'ASC') 

    return $qb->getQuery()->getResult(); 

Per questo, ho creato un "CastFunction" che si estendono "FunctionNode":

namespace Test\MyBundle\DQL; 

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

class CastFunction extends FunctionNode 
{ 
    public $firstDateExpression = null; 
    public $secondDateExpression = null; 

    public function parse(\Doctrine\ORM\Query\Parser $parser) 
    { 
     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 
     $this->firstDateExpression = $parser->ArithmeticPrimary(); 
     $parser->match(Lexer::T_IDENTIFIER); 
     $this->secondDateExpression = $parser->ArithmeticPrimary(); 
     $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
    } 

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) 
    { 
     return sprintf('CAST(%s AS %s)', $this->firstDateExpression->dispatch($sqlWalker), $this->secondDateExpression->dispatch($sqlWalker)); 
    } 
} 

Naturalmente, ho registrato questa classe nel mio config.yml:

doctrine: 
    orm: 
     dql: 
      string_functions: 
       CAST: Test\MyBundle\DQL\CastFunction 

Ora, quando cerco la mia richiesta, ottengo il seguente errore:

"[Errore semantico] riga 0, colonna 83 vicino a 'UNSIGNED'): Errore: 'UNSIGNED' non è definito."

Cerco ma non so dov'è il problema!

Hai un'idea?

risposta

10

Dopo varie ricerche, ho finalmente trovato la soluzione. Ho avuto due problemi: prima la mia funzione di analisi era errata, in secondo luogo, ho chiamato una funzione SQL nel mio orderby (grazie Cerad).

Quindi, ecco la mia corretta classe:

namespace Ypok\YPoliceBundle\DQL; 

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

class CastFunction extends FunctionNode 
{ 
    public $firstDateExpression = null; 
    public $unit = null;  

    public function parse(\Doctrine\ORM\Query\Parser $parser) 
    { 
     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 
     $this->firstDateExpression = $parser->StringPrimary(); 

     $parser->match(Lexer::T_AS); 

     $parser->match(Lexer::T_IDENTIFIER); 
     $lexer = $parser->getLexer(); 
     $this->unit = $lexer->token['value']; 

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

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) 
    { 
     return sprintf('CAST(%s AS %s)', $this->firstDateExpression->dispatch($sqlWalker), $this->unit); 
    } 
} 

E ora, posso usare perfettamente la funzione SQL 'CAST' nel mio repository:

$qb = $this->_em->createQueryBuilder(); 
$qb->select('d, CAST(d.myField AS UNSIGNED) AS sortx') 
    ->from('\Test\MyBundle\Entity\MyEntity', 'd') 
    ->orderBy('sortx', 'ASC') 

return $qb->getQuery()->getResult(); 

migliori saluti

+1

Come si accede alla proprietà "sortx" tramite oggetto? – hardik

2

Impossibile trovare il riferimento, ma le funzioni non sono consentite nella clausola order by. È necessario trasmettere il valore nell'istruzione select, quindi ordinare in base ad esso.

Qualcosa di simile:

$qb->select('d, CAST(d.myField AS UNSIGNED) AS sortx) 
    ->from('\Test\MyBundle\Entity\MyEntity', 'd') 
    ->orderBy('sortx, 'ASC') 

che sta assumendo la funzione CAST è scritto correttamente.

+0

Grazie per la tua risposta. Ma ho già provato questo codice e il problema persiste. Penso che il problema derivi dalla funzione "parse" della classe "CastFunction". Ma non capisco dove. – Scipius2012

Problemi correlati