Doctrine 2 DQL MySQL equivalent to ROUND()?

前端 未结 3 890
南笙
南笙 2020-12-19 04:35

I know from the documentation at: http://docs.doctrine-project.org/en/2.1/reference/dql-doctrine-query-language.html#dql-functions that there is no ROUND function but is the

相关标签:
3条回答
  • 2020-12-19 05:04

    A bit cleaner approach would be using slightly modified @Ocramius code.

    Put this piece of code in: src/YourNamespace/YourMainBundle/DoctrineFunctions/ directory as the Round.php filename:

    <?php
    namespace YourApp\YourMainBundle\DoctrineFunctions;
    
    use Doctrine\ORM\Query\AST\Functions\FunctionNode,
        Doctrine\ORM\Query\Lexer;
    
    class Round extends FunctionNode
    {
        private $arithmeticExpression;
    
        public function parse(\Doctrine\ORM\Query\Parser $parser)
        {
    
            $lexer = $parser->getLexer();
    
            $parser->match(Lexer::T_IDENTIFIER);
            $parser->match(Lexer::T_OPEN_PARENTHESIS);
    
            $this->arithmeticExpression = $parser->SimpleArithmeticExpression();
    
            $parser->match(Lexer::T_CLOSE_PARENTHESIS);
        }
    
        public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
        {
            return 'ROUND(' . $sqlWalker->walkSimpleArithmeticExpression($this->arithmeticExpression) . ')';
        }
    }
    

    Then put this in your app/config/config.yml:

    doctrine:
        dql:
            numeric_functions:
                round: YourApp\YourMainBundle\DoctrineFunctions\Round
    

    That would allow you to use the ROUND() function directly in your DQL SELECT queries; no matter if done with QueryBuilder or directly via createQuery()

    0 讨论(0)
  • 2020-12-19 05:13

    You need to implement a custom DQL function for that.

    There's some examples in DoctrineExtensions.

    You can implement it like following:

    <?php
    
    namespace MyApp\DQL;
    
    use Doctrine\ORM\Query\AST\Functions\FunctionNode;
    use Doctrine\ORM\Query\Lexer;
    use Doctrine\ORM\Query\SqlWalker;
    
    class Round extends FunctionNode
    {
        private $arithmeticExpression;
    
        public function getSql(SqlWalker $sqlWalker)
        {
    
            return 'ROUND(' . $sqlWalker->walkSimpleArithmeticExpression(
                $this->arithmeticExpression
            ) . ')';
        }
    
        public function parse(\Doctrine\ORM\Query\Parser $parser)
        {
    
            $lexer = $parser->getLexer();
    
            $parser->match(Lexer::T_IDENTIFIER);
            $parser->match(Lexer::T_OPEN_PARENTHESIS);
    
            $this->arithmeticExpression = $parser->SimpleArithmeticExpression();
    
            $parser->match(Lexer::T_CLOSE_PARENTHESIS);
        }
    }
    

    You can then register it in the configuration while bootstrapping the ORM:

    $config = new \Doctrine\ORM\Configuration();
    
    $config->addCustomNumericFunction('ROUND', 'MyApp\DQL\Round');
    
    0 讨论(0)
  • 2020-12-19 05:28

    If you want to be able to specify rounding precision, you can use the class that is provided here. If you are using symfony, install the bundle, as you'll also get extra standard mysql functions.

    The code of the linked resource is also available below:

    <?php
    namespace Mapado\MysqlDoctrineFunctions\DQL;
    use \Doctrine\ORM\Query\AST\Functions\FunctionNode;
    use \Doctrine\ORM\Query\Lexer;
    /**
     * MysqlRound
     *
     * @uses FunctionNode
     * @author Julien DENIAU <julien.deniau@mapado.com>
     */
    class MysqlRound extends FunctionNode
    {
        /**
         * simpleArithmeticExpression
         *
         * @var mixed
         * @access public
         */
        public $simpleArithmeticExpression;
        /**
         * roundPrecision
         *
         * @var mixed
         * @access public
         */
        public $roundPrecision;
        /**
         * getSql
         *
         * @param \Doctrine\ORM\Query\SqlWalker $sqlWalker
         * @access public
         * @return string
         */
        public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
        {
            return 'ROUND(' .
                    $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) .','.
                    $sqlWalker->walkStringPrimary($this->roundPrecision) .
            ')';
        }
        /**
         * parse
         *
         * @param \Doctrine\ORM\Query\Parser $parser
         * @access public
         * @return void
         */
        public function parse(\Doctrine\ORM\Query\Parser $parser)
        {
            $parser->match(Lexer::T_IDENTIFIER);
            $parser->match(Lexer::T_OPEN_PARENTHESIS);
            $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
            $parser->match(Lexer::T_COMMA);
            $this->roundPrecision = $parser->ArithmeticExpression();
            if ($this->roundPrecision == null) {
                $this->roundPrecision = 0;
            }
            $parser->match(Lexer::T_CLOSE_PARENTHESIS);
        }
    }
    
    0 讨论(0)
提交回复
热议问题