2013-09-30 42 views
11

我使用Symfony 2和ORM Doctrine。我想創建並註冊一個自定義的DQL函數。其實,我想使用SQL函數 「CAST」 在我的要求下,像這樣:在Doctrine和Symfony2中使用自定義DQL函數時出錯

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

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

對於這一點,我創建了一個 「CastFunction」 誰擴展 「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)); 
    } 
} 

當然,我已經註冊了這個類在我config.yml:

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

現在,當我嘗試了我的請求,我得到了以下錯誤:

「[語義錯誤]第0行,第83列'UNSIGNED'附近):錯誤:'UNSIGNED'未定義。」

我搜索,但我不知道問題在哪裏!

你有想法嗎?

回答

10

經過多次搜索,我終於找到了解決方案。我有兩個問題:第一,我的解析函數是錯誤的,第二,我在orderBy中調用了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語句中輸入你的值,然後按它排序。

喜歡的東西:

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

這是假設你的CAST功能正確寫入。

+0

謝謝爲你的答案。但我已經試過這段代碼,問題依然存在。我認爲問題來自「CastFunction」類的「解析」功能。但我不明白在哪裏。 – Scipius2012

相關問題