【问题标题】:Doctrine 2 DQL MySQL equivalent to ROUND()?Doctrine 2 DQL MySQL 等效于 ROUND()?
【发布时间】:2013-03-25 19:38:50
【问题描述】:

我从以下文档中知道: http://docs.doctrine-project.org/en/2.1/reference/dql-doctrine-query-language.html#dql-functions 没有 ROUND 函数,但有没有一种简单的方法可以在不编写我自己的 DQL 类函数的情况下做到这一点?

编辑: 如果可以进行平均并返回整数,我不需要完全匹配。

【问题讨论】:

    标签: mysql doctrine-orm


    【解决方案1】:

    您需要为此实现custom DQL function

    DoctrineExtensions中有一些例子。

    你可以像下面这样实现它:

    <?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);
        }
    }
    

    然后您可以在引导 ORM 时将其注册到配置中:

    $config = new \Doctrine\ORM\Configuration();
    
    $config->addCustomNumericFunction('ROUND', 'MyApp\DQL\Round');
    

    【讨论】:

    • 是的,这看起来是唯一的方法。我很感激这些指示。
    【解决方案2】:

    更简洁的方法是使用稍加修改的@Ocramius 代码。

    将这段代码放入:src/YourNamespace/YourMainBundle/DoctrineFunctions/目录,作为Round.php文件名:

    <?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) . ')';
        }
    }
    

    然后把这个放到你的app/config/config.yml:

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

    这将允许您直接在 DQL SELECT 查询中使用 ROUND() 函数;无论是使用 QueryBuilder 还是直接通过 createQuery()

    【讨论】:

    • 感谢很多提示,但配置“dql”必须在“orm”下(学说:orm:dql:...)。
    • 嗨!我创建了Round.php 文件,在config.yml 文件中添加了dql 代码(在doctrine : orm : entity_managers : default 键下),我运行了app/console cache:clear 命令,但我仍然无法使用ROUND我的 DQL 中的函数。这是错误:Error: Expected known function, got 'ROUND'。我还需要做什么吗?提前致谢,
    【解决方案3】:

    如果您希望能够指定舍入精度,可以使用here 提供的类。如果您使用的是 symfony,请安装该软件包,因为您还将获得额外的标准 mysql 函数。

    链接资源的代码也可以在下面找到:

    <?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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-10
      • 1970-01-01
      相关资源
      最近更新 更多