Doctrine如何使用ANY_VALUE mysql函数

时间:2016-12-30 10:39:29

标签: mysql symfony doctrine-orm

由于mysql 5.7.5分组有更改

https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

如果我进行此查询

$qb = $this->createQueryBuilder('d');
$qb->select('ANY_VALUE(d.id), d.nom, count(d.nom) as lignes');
$qb->groupBy('d.nom');   
$qb->orderBy('d.nom');

我有错误

SELECT列表的表达式#1不在GROUP BY子句中,并且包含非聚合列'sepultures.d0_.id',它在功能上不依赖于GROUP BY子句中的列;这与sql_mode = only_full_group_by

不兼容

正如在mysql doc中解释的那样,这个问题可以通过any_value解决,就像这样

$qb = $this->createQueryBuilder('d');
$qb->select('ANY_VALUE(d.id), d.nom, count(d.nom) as lignes');
$qb->groupBy('d.nom');   
$qb->orderBy('d.nom');

但是学说不承认这个功能

  

[2/2] QueryException:[语法错误]第0行,第7行:错误:预期   已知函数,得到'ANY_VALUE'

我该如何解决?

3 个答案:

答案 0 :(得分:4)

正如vincent所说,我必须创建一个函数:

<?PHP
//src/MyBundle/DoctrineExtensions/Utils/AnyValue.php

namespace DoctrineExtensions\Utils;

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

class AnyValue extends FunctionNode {

    public $value; // la valeur  passée en paramètre de la fction ANY_VALUE()

    public function parse( Parser $parser ) {
        $parser->match( Lexer::T_IDENTIFIER ); //identifie la fonction ANY_VALUE() de mysql
        $parser->match( Lexer::T_OPEN_PARENTHESIS ); //parenthèse ouvrante
        $this->value = $parser->StringPrimary();
        $parser->match( Lexer::T_CLOSE_PARENTHESIS );////parenthèse fermante
    }

    public function getSql( SqlWalker $sqlWalker ) {
        return 'ANY_VALUE(' . $this->value->dispatch( $sqlWalker ) . ')';
    }
}

在config.yml文件中声明教义扩展类(使用名为ANY_VALUE的键):

#app/config/config.yml
doctrine:        
    orm:
        auto_generate_proxy_classes: %kernel.debug%
        default_entity_manager: default
        entity_managers:
            default:
                auto_mapping: true
                connection: default
                dql:
                    string_functions:
                        ANY_VALUE: DoctrineExtensions\Utils\AnyValue

请求:

//ANY_VALUE représente la clé contenue dans le fichier config.yml
$qb = $this->createQueryBuilder('d');
$qb->select('ANY_VALUE(d.id), d.nom, count(d.nom) as lignes');
$qb->groupBy('d.nom');   
$qb->orderBy('d.nom')

答案 1 :(得分:1)

如果doctrine无法识别any_value()函数,那么您可以将查询作为原始sql语句执行:

$sql="select ANY_VALUE(d.id), d.nom, count(d.nom) as lignes from yourtable d group by d.nom"
$em->getConnection()->query( $sql ); //$em is the entity manager
...

除非你有任何参数,否则我不会使用预备语句(在示例代码中你没有)。

答案 2 :(得分:0)

非常简单的方法:

1-安装此php库:

composer require beberlei/doctrineextensions

2-在doctrine.yaml中添加以下额外配置:

doctrine:
    ...
    orm:
        ...
        dql:
            string_functions:
                MONTH: DoctrineExtensions\Query\Mysql\Month
                YEAR: DoctrineExtensions\Query\Mysql\Year
                DAY: DoctrineExtensions\Query\Mysql\Day
                ....................................

有关更多详细信息,请在此处提供官方文档: https://packagist.org/packages/beberlei/doctrineextensions