简体   繁体   English

在Doctrine DQL查询中使用COLLATE(Symfony2)

[英]Using COLLATE inside Doctrine DQL Query (Symfony2)

I can't find anything related to using COLLATE in a DQL query with Doctrine (and ofcourse it doesn't seem to work). 我找不到与使用Doctrine进行DQL查询时使用COLLATE相关的任何内容(当然它似乎不起作用)。

My specific problem: 我的具体问题:

I have a table with utf8_general_ci charset. 我有一个utf8_general_ci字符集的表。 I have one specific field in it which has accented characters (like 'á', 'ű', 'ő' etc.) 我有一个具有重音字符的特定字段(如'á','ű','ő'等)

A basic comparison with utf8_general_ci is not able to determine the difference between regular chars and their accented pairs (a = á, u = ű, o = ő), which is perfectly fine for me for the majority of the queries that land on that table! utf8_general_ci的基本比较无法确定常规字符和它们的重音对之间的区别(a =á,u =ű,o =ő),这对我来说对于大多数落在该表上的查询都是完全正确的! So if I have let's say: 所以,如果我让我们说:

 col1 |  col2
------|-------
   1  | árvíz  
------|-------
   2  | arviz

This query will return both results: 此查询将返回两个结果:

SELECT * FROM `table` WHERE `col2` = 'arviz'

Again, this is perfectly fine for me for most of the use cases! 同样,对于大多数用例来说,这对我来说非常好!

But there is one specific funcionality, where I need to determine the difference, and in regular MySQL I could use: 但是有一个特定的功能,我需要确定差异,在常规MySQL我可以使用:

SELECT * FROM `table` WHERE `col2` COLLATE utf8_bin = 'arviz'

This returns only the unaccented version. 这仅返回非重音版本。

The question is, can something like this be done using either Doctrine's createQuery (write the dql), or query builder? 问题是,可以使用Doctrine的createQuery(编写dql)或查询构建器来完成这样的事情吗?

I think I've read throught all the relevant documentation, but cannot find a way to do this. 我想我已经阅读了所有相关文档,但找不到办法做到这一点。 Is is possible somehow? 有可能吗?

Following Cerad 's suggestion to write a custom DQL function: http://www.doctrine-project.org/2010/03/29/doctrine2-custom-dql-udfs.html 遵循Cerad建议编写自定义DQL函数: http//www.doctrine-project.org/2010/03/29/doctrine2-custom-dql-udfs.html

I managed to create this: 我设法创建了这个:

namespace MyCompany\MyBundle\DQL;

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

class CollateFunction extends FunctionNode
{
    public $expressionToCollate = null;
    public $collation = null;

    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
        $this->expressionToCollate = $parser->StringPrimary();

        $parser->match(Lexer::T_COMMA);

        $parser->match(Lexer::T_IDENTIFIER);
        $lexer = $parser->getLexer();
        $this->collation = $lexer->token['value'];

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

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return sprintf( '%s COLLATE %s', $this->expressionToCollate->dispatch($sqlWalker), $this->collation );
    }
}

When registered to the config.yml ( http://symfony.com/doc/current/cookbook/doctrine/custom_dql_functions.html ) This will look for a Collate 'function' with two arguments: a field and a charset (no valid charset detection yet). 注册到config.yml时( http://symfony.com/doc/current/cookbook/doctrine/custom_dql_functions.html )这将查找带有两个参数的Collat​​e'函数':字段和字符集(没有有效的字符集)检测呢)。

Works like (written in DQL) 像(用DQL编写)的作品

COLLATE( field , collation ) 

And creates (in runable MySQL) 并创建(在可运行的MySQL中)

`field` COLLATE collation 

Ofcourse collation should be a valid charset (such as utf8_bin ) or you will get a MySQL error. Ofcourse collat​​ion应该是一个有效的charset(例如utf8_bin )或者你会得到一个MySQL错误。

I guess there is a simpler solution, but I only could create this as a 'function'. 我想有一个更简单的解决方案,但我只能将其创建为“功能”。 At least the problem is solved. 至少问题已经解决了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM