原则2 mysql字段功能按顺序排列

原则2 mysql字段功能按顺序排列,mysql,field,native,doctrine-orm,Mysql,Field,Native,Doctrine Orm,我试图在查询中的ORDERBY子句中使用MySQL字段函数。我假设条令2不支持开箱即用的场函数-是真的吗?如果是,我如何使用它?我必须将整个查询转换为本机查询吗?是否有添加此功能的Doctrine 2扩展?您可以自己编写。Jeremy Hicks,谢谢。 我不知道如何把你们的功能和条令联系起来,但最后我找到了答案 $doctrineConfig = $this->em->getConfiguration(); $doctrineConfig->addCustomStringFu

我试图在查询中的ORDERBY子句中使用MySQL字段函数。我假设条令2不支持开箱即用的场函数-是真的吗?如果是,我如何使用它?我必须将整个查询转换为本机查询吗?是否有添加此功能的Doctrine 2扩展?

您可以自己编写。

Jeremy Hicks,谢谢。 我不知道如何把你们的功能和条令联系起来,但最后我找到了答案

$doctrineConfig = $this->em->getConfiguration();
$doctrineConfig->addCustomStringFunction('FIELD', 'DoctrineExtensions\Query\Mysql\Field');
我需要
字段
函数来排序我在表达式中通过
选择的实体。但您只能在
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");

要避免将
字段
别名添加到结果行中,需要将
隐藏
关键字。因此,这就是如何在条令2.2中的表达式中对值进行排序。

您可以添加对FIELD()DQL函数的支持,但可以将其作为标准SQL案例来实现。。当表达。通过这种方式,您的函数可以在MySQL和Sqlite上工作,如果您像我一样喜欢在内存Sqlite上运行单元测试,那么这将非常有用

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

类字段扩展FunctionNode
{
私有$field=null;
private$values=array();
公共函数解析(\doctor\ORM\Query\Parser$Parser)
{
$parser->match(Lexer::T_标识符);
$parser->match(Lexer::T_OPEN_括号);
//在球场上表演。
$this->field=$parser->arithmetricprimary();
//将字符串添加到值数组。字段必须
//与至少1个不包括字段的字符串一起使用。
$lexer=$parser->getLexer();
而(计数($this->values)<1||
$lexer->lookahead['type']!=lexer::T_CLOSE_括号){
$parser->match(Lexer::T_逗号);
$this->values[]=$parser->arithmetricprimary();
}
$parser->match(Lexer::T_CLOSE_括号);
}
公共函数getSql(\doctor\ORM\Query\SqlWalker$SqlWalker)
{
$query='(CASE'.$this->field->dispatch($sqlWalker);
对于($i=0,$limiti=count($this->values);$i<$limiti;$i++){
$query.='WHEN'.$this->values[$i]->dispatch($sqlWalker)。'THEN'.$i;
}
$query.='END');
返回$query;
}
}

如果要“排序依据”的字段是枚举数据类型,则排序依据将按照为该枚举字段定义值的顺序工作


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

之后,顺序得到了修复。我尝试这样做:我不确定的部分是EBNF令牌。有人想看看我做得对不对吗?我只是使用了ArtihmeticPrimary,虽然它看起来好像我应该使用IdentificationVariable和/或FieldIdentificationVariable作为列值。我甚至找不到FieldIdentificationVariable()的函数,尽管它列在EBNF语法中。谢谢你,它成功了!下面是一种更简单的注册函数的方法:注意配置键必须是函数名您也可以简单地使用参数,例如:
->select(“r,field(r.id,:ids)as HIDDEN field”)->from(“Entities\Round”,“r”)->where(“r.id IN:ids”)->setParameter('ids',$ids)->orderBy(“field”)$query.='WHEN'$此->值[$i]->调度($sqlWalker)。'然后”。(一加一)
$query.='ELSE 0 END')
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;
    }
}