Doctrine 2 mysql FIELD函数按顺序排列

时间:2011-05-10 22:41:55

标签: mysql field native doctrine-orm

我正在尝试在查询中的order by子句中使用MySQL FIELD函数。我假设Doctrine 2不支持开箱即用的FIELD功能 - 这是真的吗?如果是这样,我该如何使用它?我是否必须将整个查询转换为本机查询?是否有添加此功能的Doctrine 2扩展名?

4 个答案:

答案 0 :(得分:23)

Jeremy Hicks,感谢your extension。 我不知道如何将你的功能与学说联系起来,但最后我找到了答案。

$doctrineConfig = $this->em->getConfiguration();
$doctrineConfig->addCustomStringFunction('FIELD', 'DoctrineExtensions\Query\Mysql\Field');

我需要FIELD函数来命令我通过IN表达式选择的实体。但是,您只能在SELECT, WHERE, BETWEEN子句中使用此功能,而不能在ORDER BY中使用。

解决方案:

$qb
            ->select("r, field(r.id, " . implode(", ", $ids) . ") as HIDDEN field")
            ->from("Entities\Round", "r")
            ->where($qb->expr()->in("r.id", $ids))
            ->orderBy("field");

要避免在结果行中添加field别名,您需要添加HIDDEN个关键字。这就是如何在Doctrine 2.2中的IN表达式中订购值。

答案 1 :(得分:6)

您可以添加对FIELD()DQL函数的支持,而是将其实现为标准SQL CASE .. WHEN表达式。这样你的函数就可以在MySQL和Sqlite上运行,如果你像我一样喜欢在内存中的sqlite上运行你的单元测试,那么这个函数特别有用。

这个课程主要基于Jeremy Hicks的工作(我只是改变了getSql()方法)

class Field extends FunctionNode
{
    private $field = null;
    private $values = array();

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

        // Do the field.
        $this->field = $parser->ArithmeticPrimary();

        // Add the strings to the values array. FIELD must
        // be used with at least 1 string not including the field.

        $lexer = $parser->getLexer();

        while (count($this->values) < 1 ||
                $lexer->lookahead['type'] != Lexer::T_CLOSE_PARENTHESIS) {
            $parser->match(Lexer::T_COMMA);
            $this->values[] = $parser->ArithmeticPrimary();
        }

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

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        $query = '(CASE ' . $this->field->dispatch($sqlWalker);
        for ($i=0, $limiti=count($this->values); $i < $limiti; $i++) {
            $query .= ' WHEN ' . $this->values[$i]->dispatch($sqlWalker) . ' THEN     ' . $i;
        }
            $query .= ' END)';

        return $query;
    }
}

答案 2 :(得分:2)

您可以自己编写DQL extension

答案 3 :(得分:0)

如果你想要的字段&#34;按顺序排列&#34;是ENUM数据类型,然后ORDER BY将按照为该ENUM字段定义值的顺序工作。

例如,我有一个定义为enum('n','pe','o','ap','c')的字段给出了奇怪的排序。将枚举更新为enum('ap','c','n','o','pe')

后,排序得到修复