2013-09-30 24 views
11

私はSymfony 2とORM Doctrineを使用します。カスタムDQL関数を作成して登録したいと思います。実際に、私はSQL関数を使用したい "CAST" 私のリクエストで、次のように:DoctrineとSymfony2でカスタムDQL関数を使用するとエラーが発生する

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)); 
    } 
} 

:このため

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

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

、私は "FunctionNodeを" 拡張 "CastFunction" を作成しましたもちろん、私は私のconfig.ymlでこのクラスを登録している:

:私は私の要求をしようとすると、

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

は今、私は次のエラーを取得します

"エラー: 'UNSIGNED'が定義されていません。

私は検索しますが、どこに問題はありません!

アイデアはありますか?

答えて

10

いくつかの検索の後、私は最終的に解決策を見つけました。私は2つの問題を抱えていました。最初に私の解析関数が間違っていました.2番目に、私はSQL関数を私の順序で呼び出しました。(ありがとうCerad)。

だから、ここに私の正しいクラスです:

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); 
    } 
} 

そして今、私は私のリポジトリに完全にSQLの関数 'CAST' を使用することができます。

$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(); 

敬具

+1

オブジェクトから「sortx」プロパティにどのようにアクセスしましたか? – hardik

2

参照は見つかりませんが、関数はorder by節では使用できません。 select文に値をキャストしてからソートする必要があります。あなたのCAST機能が正しく書かれていると仮定している

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

:よう

何か。

+0

ありがとうあなたの答えです。しかし、私はすでにこのコードを試して問題は解決していません。問題は "CastFunction"クラスの "解析"機能から来ていると思います。しかし、私はどこを理解していない。 – Scipius2012

関連する問題