创建像 IF MySQL 函数一样的自定义 DQL,但它不起作用 - [Symfony 2]

问题描述 投票:0回答:1

我打算将 IfFunction 添加到 DQL 但它不起作用:

//My DQL Class
<?php

namespace Application\HappyBundle\DQL;

use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\Lexer;

/**
 * IFFunction ::= "IF" "( "ArithmeticPrimary" , "ArithmeticPrimary" ,  "ArithmeticPrimary" )"
 */
class IFFunction extends FunctionNode
{
    // (1)
    public $firstNumericExpression = null;
    public $secondNumericExpression = null;
    public $thirdNumericExpression = null;

    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {

        $parser->match(Lexer::T_IDENTIFIER); // (2)
        $parser->match(Lexer::T_OPEN_PARENTHESIS); // (3)
        $this->firstNumericExpression = $parser->ArithmeticPrimary(); // (4)
        $parser->match(Lexer::T_COMMA); // (5)
        $this->secondNumericExpression = $parser->ArithmeticPrimary(); // (6)
        $parser->match(Lexer::T_COMMA); // (5)
        //$parser->match(Lexer::T_CLOSE_PARENTHESIS); // (3)
        $this->thirdNumericExpression = $parser->ArithmeticPrimary(); // (6)
        $parser->match(Lexer::T_CLOSE_PARENTHESIS); // (3)

    }

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return 'IF(' .
            $this->firstNumericExpression->dispatch($sqlWalker) . ', ' .
            $this->secondNumericExpression->dispatch($sqlWalker) . ', ' .
            $this->thirdNumericExpression->dispatch($sqlWalker) .
        ')';
    }
}

//config.yml 中的声明

        dql:
            datetime_functions:
                timediff: Application\HappyBundle\DQL\TimeDiff  
                addtime: Application\HappyBundle\DQL\AddTime    
            numeric_functions:
                IF: Application\HappyBundle\DQL\IFFunction            

添加 DQL 函数可以工作,但是当我打算这样做时:

SELECT IF(1<2,'oui','non');

字符'<' If i put the If function like this

有错误
SELECT IF('1<2','oui','non');

它可以工作,但不能评估第一个条件:(

如果有人有想法...... 谢谢你的帮助。

mysql symfony if-statement doctrine-orm dql
1个回答
6
投票

我找到了解决方案,问题出在解析器上,它必须包含像这样的

ConditionalExpression
来评估:

class IfFunction extends FunctionNode
{
    private $expr = array();

    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
        $this->expr[] = $parser->ConditionalExpression();

        for ($i = 0; $i < 2; $i++)
        {
            $parser->match(Lexer::T_COMMA);
            $this->expr[] = $parser->ArithmeticExpression();
        }

        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return sprintf('IF(%s, %s, %s)',
            $sqlWalker->walkConditionalExpression($this->expr[0]),
            $sqlWalker->walkArithmeticPrimary($this->expr[1]),
            $sqlWalker->walkArithmeticPrimary($this->expr[2]));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.