Доктрина 2 mysql ПОЛЕ функция в порядке - PullRequest
13 голосов
/ 11 мая 2011

Я пытаюсь использовать функцию MySQL FIELD в порядке упорядочения в запросе.Я предполагаю, что Doctrine 2 не поддерживает функцию FIELD из коробки - это правда?Если так, как я могу использовать это?Должен ли я превратить весь свой запрос в собственный запрос?Есть ли расширение Doctrine 2, которое добавляет эту функциональность?

Ответы [ 4 ]

23 голосов
/ 15 апреля 2012

Джереми Хикс, спасибо за ваше расширение .Я не знал, как связать вашу функцию с доктриной, но, наконец, я нашел ответ.

$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.Вот так можно уметь упорядочивать значения в выражении IN в Doctrine 2.2.

6 голосов
/ 21 ноября 2012

Вы можете добавить поддержку функции DQL FIELD (), но вместо этого реализовать ее как стандартное выражение SQL CASE .. WHEN.Таким образом, ваша функция будет работать как на MySQL, так и на Sqlite, что особенно полезно, если вы похожи на меня и хотите запускать свои модульные тесты на sqlite в памяти.

Этот класс в значительной степени основан на работе ДжеремиХикс (я просто изменил метод 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 голосов
/ 25 мая 2011

Вы можете написать собственное расширение DQL .

0 голосов
/ 12 июля 2017

Если поле, которое вы хотите "упорядочить", относится к типу данных ENUM, то ORDER BY будет работать в том порядке, в котором были определены значения для этого поля ENUM.

Например, у меня было поле, определенное как enum('n','pe','o','ap','c'), которое давало странный порядок. Порядок исправлен после обновления перечисления: enum('ap','c','n','o','pe')

...