2013-09-30 40 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

相关问题