Я пытаюсь использовать естественную сортировку в MySQL через построитель запросов доктрины. Но функция orderBy() не имеет нужных мне параметров.
Это запрос, который мне нужно передать доктрине:
SELECT * FROM `ouvidoria`
ORDER BY CAST(RIGHT(`id`, LENGTH(`id`)-3) AS UNSIGNED) DESC;
я пробовал следующее:
public function getLastKeyOfOrigin($origin) {
$data = $this->getRepository()->findOneBy(['origin'=>$origin->getId()]);
$select = $this->em->createQueryBuilder();
$select->select('o')
->from($this->entityPath, 'o')
->where("o.origin = :origin")
->setParameter('origin', $origin)
->orderBy('CAST(RIGHT(o.id, LENGTH(o.id)-3) AS UNSIGNED)', 'DESC')
->setMaxResults('1');
return $select->getQuery()->getOneOrNullResult();
}
который дает следующую ошибку:
Type: Doctrine\ORM\Query\QueryException Message: [Syntax Error] line 0, col 79: Error: Expected known function, got 'CAST'






Вы можете сделать это:
$select->select('o')
->from($this->entityPath, 'o')
->where("o.origin = :origin")
->setParameter('origin', $origin)
->addSelect('CAST(RIGHT(o.id, LENGTH(o.id)-3) AS UNSIGNED) AS HIDDEN orderCol')
->orderBy('orderCol', 'DESC')
->setMaxResults('1');
Таким образом, вы сохраняете простоту orderBy(), используя псевдоним, определенный в другом месте, и это помогает вам преодолеть его ограничения.
О, теперь я вижу, проблема была не в сложности выражения, а в использовании функций SQL, которые не переопределяются как функции DQL. Да, в данном случае мой совет просто не имеет отношения к делу. Я думаю, что вам лучше всего использовать собственный запрос, то есть сделать его на простом SQL (doctrine-project.org/projects/doctrine-orm/en/2.6/reference/…). Или вы можете реализовать эти недостающие функции (или создать новую, которая делает то, что вы хотите), но я думаю, что это просто излишество.
Жаль, что Doctrine (AFAIK) не позволяет просто вставить фрагмент SQL в QueryBuilder, в отличие, например, от Красноречивый от Laravel. Я предполагаю, что это сломало бы некоторые сильные абстракции в Doctrine.
Я, вероятно, в конечном итоге пойду на излишество, перестройка всей системы для использования собственного запроса будет еще хуже. :/
Этот один запрос не кажется таким уж плохим, я имею в виду, что вы можете использовать собственный запрос прямо здесь, без каких-либо изменений в любом другом месте. Зачем вам переделывать всю систему?
А, и обязательный комментарий: кажется, у вас есть два связанных, но разных значения в одном и том же столбце. Это не нормированные данные. Вместо этого у вас должно быть два столбца (возможно, 3, если вам нужно объединить оба значения, но в этом случае виртуальный столбец будет лучше). Но это будет «перестройка всей системы», да.
Я решил это, упорядочив запрос по 2 столбцам, но отвечая на заданный вопрос, вы можете использовать класс NativeQuery доктрины для отправки открытого SQL через доктрину.
спасибо за ответ, но это все еще дает ту же ошибку.