我使用Symfony 2和ORM Doctrine。我想创建并注册自定义DQL函数。实际上,我想在我的请求中使用SQL函数“CAST”,如下所示:
$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”:
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'。”
我搜索但我不知道问题在哪里!
你有个主意吗?
答案 0 :(得分:10)
经过多次搜索,我终于找到了解决方案。我有两个问题:首先我的解析函数是错误的,第二,我在我的订单中调用了一个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 :(得分:2)
无法找到引用,但order by子句中不允许使用函数。您需要在select语句中转换值,然后按它排序。
类似的东西:
$qb->select('d, CAST(d.myField AS UNSIGNED) AS sortx)
->from('\Test\MyBundle\Entity\MyEntity', 'd')
->orderBy('sortx, 'ASC')
假设您的CAST功能写得正确。