Я использую Symfony 2 и доктрину ORM. Я хочу создать и зарегистрировать пользовательскую функцию 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();
Для этого я создал «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 »не определен».
Я ищу, но я не знаю, где проблема!
У вас есть идея?
После нескольких поисков я наконец нашел решение. У меня было две проблемы: сначала моя функция синтаксического анализа была неправильной, во-вторых, я назвал функцию 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();
С наилучшими пожеланиями
Невозможно найти ссылку, но функции не разрешены в предложении order by. Вам нужно указать ваше значение в инструкции select, а затем отсортировать его.
Что-то вроде:
$qb->select('d, CAST(d.myField AS UNSIGNED) AS sortx) ->from('\Test\MyBundle\Entity\MyEntity', 'd') ->orderBy('sortx, 'ASC')
Это предполагает, что ваша функция CAST написана правильно.