8

http://docs.doctrine-project.org/en/2.1/reference/dql-doctrine-query-language.html#dql-functionsのドキュメントから、 ROUND関数はありませんが、簡単な方法があることがわかります。独自のDQLクラス関数を記述せずにそれを行うには?

編集: 平均を実行して整数を返すことが可能であれば、完全に一致する必要はありません。

4

3 に答える 3

8

そのためにカスタムDQL関数を実装する必要があります。

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');
于 2013-03-26T05:48:44.363 に答える
8

少しクリーンなアプローチは、わずかに変更された@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

ROUND()これにより、DQLSELECTクエリで関数を直接使用できるようになります。QueryBuilderを使用するか、直接経由するかに関係なくcreateQuery()

于 2015-03-30T07:20:56.700 に答える
5

丸め精度を指定できるようにする場合は、ここで提供されているクラスを使用できます。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);
    }
}
于 2015-06-22T08:01:21.233 に答える