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

PHP & Base de données Discussion :

[Doctrine] Requête select imbriquée dans un where not in


Sujet :

PHP & Base de données

  1. #1
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut [Doctrine] Requête select imbriquée dans un where not in
    Messieurs dames,

    soit une hiérarchie de catégories. Chaque catégorie peut avoir plusieurs parents et plusieurs enfants.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    Category:
      columns:
        tag:
          type: string(20)
     
    CategoryHasCategory:
      columns:
        child_category_id:
          type: integer
          primary: true
          notnull: true
        parent_category_id:
          type: integer
          primary: true
          notnull: true
      relations:
        ParentCategory:
          class: Category
          local: parent_category_id
          foreignAlias: LinksToChildrenCategories
        ChildCategory:
          class: Category
          local: child_category_id
          foreignAlias: LinksToParentCategories
    Je cherche la liste des catégories racines, donc les catégories qui ne sont pas présentes dans CategoryHasCategory en tant que catégories filles. En SQL, facile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from Category where id not in (select distinct(child_category_id) from CategoryHasCategory)
    Malheureusement, Doctrine ne l'entend pas de cette oreille :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        public static function getRootCategoriesQuery(Doctrine_Query $q = null) {
    	if(!$q) {
    	    $q = self::getInstance()->createQuery();
    	}
     
    	$rootAlias = $q->getRootAlias();
    	return $q->andWhere("$rootAlias.id NOT IN(SELECT CategoryHasCategory.child_category_id FROM CategoryHasCategory)");
        }
    donne comme code SQL généré par Doctrine :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	$q = CategoryTable::getRootCategoriesQuery()->execute();
    ---> SQL généré : 
    SELECT c.* FROM category c, category_has_category c2 WHERE (c.id NOT SELECT c2.child_category_id FROM CategoryHasCategory IN ()) - ()
    N'importe quoi, donc...

    Je vais provisoirement contourner le problème en construisant le tableau des ids des catégories filles et en le passant au addWhere en argument, ce qui élimine la requête imbriquée. Mais ce qui m'intéresserait serait plutôt de construire le DQL avec requête imbriquée pour que Doctrine le comprenne.

  2. #2
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    As-tu regardé du côté de Doctrine_RawSql ?

  3. #3
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Hélas oui. Note que dans l'idéal, avec toutes les vertus que les concepteurs de Symfony et de Doctrine prêtent à leur produit, je m'attends plutôt à pouvoir utiliser le DQL fourni par cet ORM. Je déduis de ta question que ce n'est pas possible, donc ?

    Côté RawSql, j'ai d'autres problèmes.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	$q = new Doctrine_RawSql();
    	$q->select('distinct {c.child_category_id}')
    		->from('category_has_category c')
    		->addComponent('c', 'CategoryHasCategory')
    		->execute();
    me fait bien une requête correcte, mais sans le 'distinct'.

    Rien de grave bien sûr, je peux dédoublonner moi-même les résultats. Mais une fois de plus, j'ai l'impression que le couple Doctrine/Symfony rend compliquée une chose qui devrait être simple...

  4. #4
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Ha oui, et puis j'ai aussi ça comme résultats dans mes traces :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	$q = new Doctrine_RawSql();
    	$rows = $q->select('{c.child_category_id}')
    		->from('category_has_category c')
    		->addComponent('c', 'CategoryHasCategory')
    		->execute(Doctrine_Core::HYDRATE_SCALAR);
    --->
    Mar 28 09:13:06 symfony [info] {Doctrine_Connection_Statement} execute : SELECT c.child_category_id AS c__child_category_id, c.parent_category_id AS c__parent_category_id FROM category_has_category c - (5)
    De toute évidence, Doctrine se fiche pas mal qu'on ait besoin d'une colonne ou de toutes, tout comme il se fiche de la clause DISTINCT. En outre, des logs additionnels montrent que Doctrine me renvoie une série d'objets de la classe CategoryHasCategory et non pas un tableau associatif.

    Comment faire pour qu'il effectue la requête demandée ? Ai-je raté quelque chose dans son paramétrage ?

  5. #5
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Effectivement, doctrine 1 ne sait pas faire de requêtes imbriquées. C'est indiqué dans la documentation (mais où ? ! ), en tout cas, je l'y ai lu.

    Il n'y a aucun paramétrages général qui permettraient de simplifier... Hélas.

    Le problème des requêtes imbriquées et de Doctrine, c'est la portabilité. En effet, l'objectif de Doctrine est de permettre à ton code de travailler sur n'importe quel moteur de base de données sans avoir à réécrire du code. Ce qui, dans certains cas, à une tendance gênante mais naturel à compliquer largement la situation.

    A priori, pour que les commandes sql passent bien dans doctrine elles doivent être en MAJUSCULE.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $q->select('DISTINCT {c.child_category_id}')

  6. #6
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Citation Envoyé par Michel Rotta Voir le message
    Effectivement, doctrine 1 ne sait pas faire de requêtes imbriquées. C'est indiqué dans la documentation (mais où ? ! ), en tout cas, je l'y ai lu.
    Leur doc n'est pas à jour en ce cas : DQL/subqueries (1.2)

    Pour le raw sql, j'ai essayé avec des majuscules, des minuscules, des caractères cyrilliques, en dansant devant mon bureau, en ahanant des litanies mystiques, en string, en costard cravate, avec ou sans gants cloutés. Rien n'y fait.

    Je pense que c'est un complot.

  7. #7
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Il n'y a pas contradiction avec ce que je dis. DQL ne supporte pas les sous requêtes, il faut les exprimer en SQL.

    Après, il faudrait que je fasse des tests avec ton modèle et du temps, les deux me manquent, le deuxième cruellement...

Discussions similaires

  1. requête SELECT imbriquée dans INSERT
    Par bensh dans le forum JDBC
    Réponses: 0
    Dernier message: 23/10/2017, 23h08
  2. select imbriquée dans un curseur
    Par zinabd dans le forum Oracle
    Réponses: 3
    Dernier message: 19/01/2009, 15h03
  3. [MySQL] Requête SELECT insérée dans un WHILE
    Par boubourse92 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 17/01/2008, 16h01
  4. Recupérer la valeur d'un select imbriqué dans un update
    Par miniil dans le forum Langage SQL
    Réponses: 3
    Dernier message: 07/07/2006, 10h49
  5. Requête SELECT problème dans les résultats trouvés ...
    Par snoopy69 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 18/10/2005, 12h46

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