IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Doctrine2 PHP Discussion :

Requête Doctrine - ORDER BY et LOWER


Sujet :

Doctrine2 PHP

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 31
    Par défaut Requête Doctrine - ORDER BY et LOWER
    Bonjour à tous,

    J'ai un écran de recherche, dans lequel l'utilisateur peux saisir différents critères. Ma requête de recherche se construit au fur et à mesure. Un clic sur la colonne du tableau de résultats permet d'effectuer des tris. Or il y a un premier tri sur les minuscules puis sur les majuscules. J'ai donc essayé de changer mon order by pour que tout soit en minuscule, mais une erreur est ressorti avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $qb->addOrderBy(" LOWER (c.nom)");
    exception 'Doctrine\ORM\Query\QueryException'; with message '[Syntax Error] line 0, col 245: Error: Expected end of string, got '('' in ....
    Si vous avez une solution à mon problème, je suis preneur

    NB : Le tri fonctionne sans le LOWER() (mais ne prends pas en compte la distinction MAJ/MIN).

    Merci pour votre aide !

  2. #2
    Membre éprouvé
    Homme Profil pro
    Chef d'entreprise
    Inscrit en
    Mai 2011
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef d'entreprise
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2011
    Messages : 122
    Par défaut
    Bonjour,

    Essaie en passant par la classe Expr:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ->addOrderBy($qb->expr()->lower('c.nom'))

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 31
    Par défaut
    J'y avais bien pensé ! Mais le problème est le même !!

  4. #4
    Membre éprouvé
    Homme Profil pro
    Chef d'entreprise
    Inscrit en
    Mai 2011
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef d'entreprise
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2011
    Messages : 122
    Par défaut
    Le problème est le même, mais encore... Le message d'erreur est le même ?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 31
    Par défaut
    Citation Envoyé par Francesco34 Voir le message
    Le problème est le même, mais encore... Le message d'erreur est le même ?
    Oui le message d'erreur est le même !!

  6. #6
    Membre éprouvé
    Homme Profil pro
    Chef d'entreprise
    Inscrit en
    Mai 2011
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef d'entreprise
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2011
    Messages : 122
    Par défaut
    Fais voir ce que tu as dans ton repository.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2012
    Messages : 6
    Par défaut
    J'ai exactement le même problème avec Symfony2 / Doctrine donc je me permets d'apporter la solution HORRIBLE que je suis contraint d'utiliser.

    Ma fonction devait ressembler à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // "src\App\AppBundle\Entity\ActesRepository.php"
    // Ne fonctionne pas
    public function findAll() {
            $query = $this->getEntityManager()->createQueryBuilder();
            $query->select('a')
                    ->from('\App\AppBundle\Entity\Actes', 'a')
                    ->orderBy($query->expr()->lower('a.libelle'))
                    ;
            $query = $query->getQuery();
            return $query->getResult();
    }
    J'ai aussi essayé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ->orderBy('LOWER(a.libelle)')
    J'avais l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [Syntax Error] line 0, col 67: Error: Expected end of string, got '('
    Donc à défaut d'une solution propre, je fais ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    // "src\App\AppBundle\Entity\ActesRepository.php"
    // Fonctionne
    public function findAll() {
              $query = "SELECT id FROM actes ORDER BY LOWER(libelle)";
              $results = $this->getEntityManager()->getConnection()->fetchAll($query);
     
              $actes = array();
              foreach($results as $result){
                        $actes[] = $this->find($result['id']);
              }
              return $actes;
    }
    En espérant que quelqu'un repasse par là et puisse apporter une réponse de meilleure qualité ...

  8. #8
    Membre émérite
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Par défaut
    Ce n'est pas parfait, mais tu dois pouvoir réduire le nombre de requetes ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public function findAll() {
              $sql = "SELECT id FROM actes ORDER BY LOWER(libelle)";
              $ids = $this->getEntityManager()->getConnection()->fetchAll($sql);
     
               $dql = "SELECT a FROM MyBundle:Acte WHERE a.id IN (:ids)";
              return $this->getEntityManager()->createQuery($dql)->setParameter('ids',$ids)->getQuery()->getResult();
    }

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2012
    Messages : 6
    Par défaut
    [EDIT]

    Ta solution est effectivement plus rapide mais le ne conserve pas l'ordre des lignes de la requête précédente !

    Cela ne résout donc pas mon problème.

    [Réponse initiale] :

    Merci, je n'y avais pas pensé !

    J'ai corrigé ce que tu proposes car le format des résultats de fetchAll() n'est pas adapté pour setParameter().

    Il faut aussi faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ->createQuery($dql)->getResult();
    et pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ->createQuery($dql)->getQuery()->getResult();
    Cette version fonctionne mais ne retourne pas le résultat attendu, les entités retournées par getResult() ne respectent pas l'ordre de ma première requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public function findAll() {
            $query = "SELECT id FROM actes ORDER BY LOWER(acte)";
            $results = $this->getEntityManager()->getConnection()->fetchAll($query);
     
            //$results est un tableau de tableaux ...
            //Je le convertis donc en tableau simple
            $actes = array();
            foreach($results as $result){
                $actes[] = $result['id'];
            }
     
            $query = "SELECT a FROM \App\AppBundle\Entity\Actes a WHERE a.idUnique IN (:ids)";
            return $this->getEntityManager()->createQuery($query)->setParameter('ids', $actes)->getResult();
    }
    Cette dernière solution est jusqu'à 10 ou 15 fois plus rapide que la mienne mais perd le classement initial ...

  10. #10
    Membre éprouvé
    Homme Profil pro
    Chef d'entreprise
    Inscrit en
    Mai 2011
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef d'entreprise
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2011
    Messages : 122
    Par défaut
    Bonjour,

    Qu'est-ce qui "ne fonctionne pas" dans ta première méthode findAll() ?

  11. #11
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2012
    Messages : 6
    Par défaut
    Le queryBuilder ne supporte pas la fonction LOWER() dans un ORDER BY.

    ça génère cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [Syntax Error] line 0, col 67: Error: Expected end of string, got '('

  12. #12
    Membre éprouvé
    Homme Profil pro
    Chef d'entreprise
    Inscrit en
    Mai 2011
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef d'entreprise
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2011
    Messages : 122
    Par défaut
    Je parlais de ton utilisation de expr(), tu mets un commentaire "Ne fonctionne pas" mais sans préciser ce qui se passe (ou pas).

    Sinon, je ne sais pas si cela fonctionne en DQL mais as-tu essayé ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $dql = "SELECT a FROM MyBundle:Acte ORDER BY acte COLLATE utf8_general_ci"
    return $this->getEntityManager()->createQuery($dql)->getResult();

  13. #13
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2012
    Messages : 6
    Par défaut
    Quand j'essaye de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $query->select('a')
                    ->from('\App\AppBundle\Entity\Actes', 'a')
                    ->orderBy($query->expr()->lower('a.libelle'));
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $query->select('a')
                    ->from('\App\AppBundle\Entity\Actes', 'a')
                    ->orderBy('LOWER(a.libelle)');
    J'ai l'erreur indiquée dans mon précédent message, ce n'est pas un problème avec expr(), c'est juste que la fonction orderBy() n'accepte pas les fonctions LOWER() et UPPER() ...

  14. #14
    Membre éprouvé
    Homme Profil pro
    Chef d'entreprise
    Inscrit en
    Mai 2011
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef d'entreprise
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2011
    Messages : 122
    Par défaut
    Désolé, j'avais compris que cette erreur ne concernait que la seconde forme.

    Quoiqu'il en soit, je ne pense pas que le fond de ton problème vienne de l'utilisation de la fonction expr() mais plutôt du fait que ton champ acte est sensible à la casse et que tu souhaites qu'il ne le soit pas lors de ton tri (d'où l'ajout de COLLATE que je te propose dans mon message précédent).

    Ceci dit, je pense que le plus simple est de modifier ta base de données pour rendre le champ acte insensible à la casse.

  15. #15
    Membre émérite
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Par défaut
    une autre proposition (non testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $dql = "SELECT a, 
                          LOWER(a.libelle) AS HIDDEN lower_libelle
               FROM MyBundle:Acte
               ORDER BY lower_libelle";
    exemple ici :http://michelsalib.com/2012/03/04/do...idden-keyword/

  16. #16
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2012
    Messages : 6
    Par défaut
    Je pourrais aussi gérer la casse des colonnes concernées en amont ... mais ça serait trop facile !

    La base de données existe déjà, avec tous ses défauts, je dois me démerder avec...

    @arnooo999 :

    Je n'ai pas pu tester ta solution, elle ne fonctionne que sous Doctrine 2.2+ et le projet est sous la version 2.1 ... Une mise à jour n'est pas envisagée

    Merci quand même, ça avait l'air plus pratique, je garde ça de côté !

  17. #17
    Membre émérite
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Par défaut
    Tu dois pouvoir faire aussi
    $dql = "SELECT a,
    LOWER(a.libelle) AS lower_libelle
    FROM MyBundle:Acte
    ORDER BY lower_libelle";
    le probleme est que la récupération des résultats est moins pratique, au lieu de récupérer un tableau d'entité, tu récupére un tableau composé de tableaux dont la premiere valeur est l'entité et la seconde le lower_libelle

Discussions similaires

  1. Probleme sur requête avec order by multiple
    Par dembroski dans le forum Requêtes
    Réponses: 25
    Dernier message: 28/01/2010, 16h47
  2. Réponses: 6
    Dernier message: 18/06/2009, 23h25
  3. Requête avec ORDER BY et DESC
    Par Daddy91 dans le forum Requêtes
    Réponses: 9
    Dernier message: 31/03/2009, 12h20
  4. [Oracle 10] Bizzareté requête avec order by ??
    Par Eric.H dans le forum Oracle
    Réponses: 12
    Dernier message: 22/06/2005, 13h36
  5. Requête bizarre ... Order by sur 2 champs
    Par MatthieuQ dans le forum Langage SQL
    Réponses: 9
    Dernier message: 10/06/2004, 15h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo