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 :

fetch() sur Requete multitable


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Retraité Ing Electronique
    Inscrit en
    Mars 2004
    Messages
    369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Retraité Ing Electronique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2004
    Messages : 369
    Par défaut fetch() sur Requete multitable
    Bonjour,

    Je suis en train de passer un site plateforme de mysql à PDO avec plus de 1000 requêtes à la base de données.

    Ce site utilise pas mal de requêtes multitables dans lesquelles deux tables peuvent posséder des champs avec des noms identiques.
    Ayez aussi à l'idée, que ces requêtes multitables peuvent, dans certain cas, faire appel plusieurs fois à la même table, et donc avec des noms de données forcément identiques.

    Voila comment on s'en sortait avec mysql sur une requête faisant appel à 2 fois la même table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $requete = "SELECT t1.data, t2.data FROM table t1";
    $requete = $requete . "LEFT JOIN table t2 ON t2.id2=t1.id1 WHERE  ...";
    $resultat = mysql_query($requette)
    $num_rows = mysql_num_rows($resultat)
    Pour accéder aux données on faisait par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for($row=0;$row<$num_rows;$row++) {
    data1 = mysql_result($resultat,$row,'t1.data');
    data2 = mysql_result($resultat,$row,'t2.data');
    }
    Avec PDO, j'ai voulu retranscrire cette requette avec des fetch(). pour accéder aux données, j'avais pensé faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $resultat = $bdd->query($requette)
    while($row=$resultat->fetch()) {
    $data1 = $row['t1.data']
    $data2 = $row['t2.data']
    }
    Mais PDO me refuse l'écriture t1.data et ne reconnait pas les data concernées

    Alors faut il que l'utilisation de PDO nous force à intervenir dans les requettes sql ?

    En faisant par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $requete = "SELECT t1.data as data1, t2.data as data2 from table1 t1";
    $requete = $requete . "LEFT JOIN table2 t2 ON t2.id=t1.id WHERE  t1.id = NB";
    $resultat = $bdd->query($requete)
    while($row=$resultat->fetch()) {
    $data1 = $row['data1']
    $data2 = $row['data2']
    }
    Merci de vos réponses éclairées

    Zakuli

  2. #2
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    Je ne m'étais jamais posé la question car je nomme tous les champs aliassés.
    Je ne sais pas si le code ci-dessous peut t'être utile mais cela peut te donner des idées.

    Code php : 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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    <?php 
    class toto {
     
     private $array_names;
     private $pdoStatement;
     
     public function __construct(&$pdoStatement) {
      $this->pdoStatement = $pdoStatement;
      $this->array_names  = array(); 
      for ($i=0;$i<$this->pdoStatement->columnCount();$i++) {
       $meta = $this->pdoStatement->getColumnMeta($i);
       $this->array_names[$i] = $meta['table'].'.'.$meta['name'];
      } 
     }
     
     public function fetch() {
      $ret = array();
      $row = $this->pdoStatement->fetch();
      if ($row !== false) {
       for ($i=0;$i<$this->pdoStatement->columnCount();$i++) {
        $meta = $this->pdoStatement->getColumnMeta($i);
        $ret[$this->array_names[$i]] = $row[$i];
       }  
       return $ret;
      } else {
       return $row;
      }
     }
    }
    //=================================================================================
    define('DB_HOST', '127.0.0.1');
    define('DB_NAME', 'tests');
    define('DB_USER', 'root');
    define('DB_PWD' , '');
    $bdd         = new PDO('mysql:host='.DB_HOST.'; dbname='.DB_NAME,DB_USER,DB_PWD, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
    $query       = "SELECT u1.username, u1.password, u2.username, u2.password as toto FROM `utenti` u1 INNER JOIN `utenti` u2 ON u1.username = u2.username ";
    $prepared    = $bdd->prepare($query);
    $prepared->execute();
    $titi        = new toto($prepared);
    while($row=$titi->fetch()) {
     $data1 = $row['u1.username'];
     $data2 = $row['u1.password']; 
     $data3 = $row['u2.username'];
     $data4 = $row['u2.toto'];  
     print "$data1 - $data2 - $data3 - $data4 <br/>";
    }

  3. #3
    Membre éclairé
    Homme Profil pro
    Retraité Ing Electronique
    Inscrit en
    Mars 2004
    Messages
    369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Retraité Ing Electronique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2004
    Messages : 369
    Par défaut
    Merci badaze,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $data1 = $row['u1.username'];
    $data3 = $row['u2.username'];
    Et ce code marche chez toi ?
    Il dissocie bien les deux données ?

  4. #4
    Membre émérite Avatar de Willy_k
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 541
    Par défaut
    Bonjour,
    Tu peux utiliser ça en bas de ta connexion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $bdd->setAttribute(PDO::ATTR_FETCH_TABLE_NAMES, true);
    http://php.net/manual/fr/pdo.constants.php pour plus d'infos sur les autres constantes
    Sinon pourquoi tu ne veux pas utiliser d'alias ?

  5. #5
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    @Willy_k. J'avais cherché un truc comme ça mais je ne l'avais pas trouvé.

    @zakuli. Dans mon cas ce sont les mêmes données (cf l'INNER JOIN) mais ce ne sont pas les mêmes champs (cf le SELECT).

  6. #6
    Membre éclairé
    Homme Profil pro
    Retraité Ing Electronique
    Inscrit en
    Mars 2004
    Messages
    369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Retraité Ing Electronique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2004
    Messages : 369
    Par défaut
    Merci badaze,

    Citation Envoyé par badaze Voir le message
    @zakuli. Dans mon cas ce sont les mêmes données (cf l'INNER JOIN) mais ce ne sont pas les mêmes champs (cf le SELECT).
    Je ne comprends pas très bien ta réponse, car il me semble que tu utilises deux fois la même table "utenti" contenant au moins les deux champs "username" et "password"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $query = "SELECT u1.username, u1.password, u2.username, u2.password as toto FROM `utenti` u1 INNER JOIN `utenti` u2 ON u1.username = u2.username ";
    La requête me semble parfaite comme exemple d'appel multiple à la même table dans une requête SQL (bien que cette requête n'aurait pas grand intérêt dans la mesure où elle fait appel deux fois au à la même ligne de la table).

    Mais si le code ci-dessous est accepté par ton driver, elle montrerait que chez toi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $data1 = $row['u1.username'];
    $data3 = $row['u2.username'];
    PDO fonctionnerait bien dans ce cadre, raison de ma question.

    Cordialement

    Zakuli

  7. #7
    Membre émérite Avatar de Willy_k
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 541
    Par défaut
    Pour la mise en production trop tôt, je pense que si c'était le cas, elle ne serait pas aussi utilisée enfin c'est votre avis...
    Peut être que j'ai du mal à comprendre ce que vous demandez, mais j'ai essayé ça chez moi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <?php
     
    $bdd = new PDO('mysql:host=localhost;dbname=test_db;charset=utf8', 'root', 'root');
    $bdd->setAttribute(PDO::ATTR_FETCH_TABLE_NAMES, true);
     
    $query = $bdd->query('SELECT t1.data, t2.data FROM tables t1 JOIN tables t2 ON t1.toto = t2.tata');
    while ($row= $query->fetch()) {
        echo $row['t1.data'], $row['t2.data']; 
    }
    Mon driver est mysql, encore une fois peut être que j'ai mal compris la demande

  8. #8
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    @Zakuli
    L'exemple de ma requête est trivial. Je n'avais que cette table sous la main.
    C'est la class toto qui fait le boulot. Elle compose les noms des champs et fait le fetch. Attention. C'est un truc fait en 20 minutes donc ce n'est pas spécialement très étudié. Mon but étant de montrer une possibilité.

    Comme je l'écrivais dans mon premier message, j'ai pris l'habitude de nommer tous mes champs donc je n'ais pas ce problème quand je passe de mysql à PDO.

  9. #9
    Membre éclairé
    Homme Profil pro
    Retraité Ing Electronique
    Inscrit en
    Mars 2004
    Messages
    369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Retraité Ing Electronique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2004
    Messages : 369
    Par défaut
    Merci willy,

    En première approche, tel qu'énoncée dans sa définition (cf ci-dessous), il me semble que PDO::ATTR_FETCH_TABLE_NAMES ne répond pas vraiment à l'accès multiple à une même table !

    Tu me demandes :Sinon pourquoi tu ne veux pas utiliser d'alias ?
    Personnellement, je trouve tout à fait anormal que le choix du driver impose de modifier les requêtes sql.

    Le driver devrait être capable d'utiliser n'importe quel résultat de requête à la condition bien sûr qu'elle soit conforme à la norme SQL.

    Je trouve le langage SQL extrêmement bien fait et PDO n'en n'est pour l'instant pas à la hauteur.

    J'ai choisi de passer de mysql à PDO, parce qu'on me disait que PDO était beaucoup mieux et avait plus d'avenir que mysqli. Je sais que PDO est toujours en construction, et j'espère qu'il va évoluer rapidement vers un meilleur respect de la norme SQL, mais je me demande si je n'aurais pas dû attendre un peu plus de fiabilité.

    En effet, j'ai déjà repéré quelques bugs avec PDO (avec PDO::closeCursor()) + ce problème d'accès multiple à une même table, ça montre bien que PDO a été mis en production un peu tôt !

    Cordialement et merci à tous

    Zakuli

    PS : définition de PDO::ATTR_FETCH_TABLE_NAMES : Ajoute le contenu de la table de noms dans chaque nom de colonne retourné dans le jeu de résultats. La table de nom et les noms de colonnes sont séparés par un point (.). Le support de cet attribut n'est pas disponible pour tous les pilotes ; il peut ne pas être disponible pour votre driver.
    Donc dans le cas d'un accès multiple à la même table dans une requête il n'y aura pas plus de différenciation entre les données de même nom !

  10. #10
    Membre éclairé
    Homme Profil pro
    Retraité Ing Electronique
    Inscrit en
    Mars 2004
    Messages
    369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Retraité Ing Electronique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2004
    Messages : 369
    Par défaut
    Merci Willy,

    Oui, mon driver est aussi mysql.

    Oui, c'est bien ce que je cherche à faire marcher comme requête, mais tu ne me dis pas si ça fonctionne correctement chez toi !

    Chez moi, l'écriture echo $row['t1.data'], $row['t2.data']; est refusée et pour que ça marche, je dois écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    $bdd = new PDO('mysql:host=localhost;dbname=test_db;charset=utf8', 'root', 'root');
    $bdd->setAttribute(PDO::ATTR_FETCH_TABLE_NAMES, true);
     
    $query = $bdd->query('SELECT t1.data as data1, t2.data as data2 FROM tables t1 JOIN tables t2 ON t1.toto = t2.tata');
    while ($row= $query->fetch()) {
        echo $row['data1'], $row['data2']; 
    }

  11. #11
    Membre émérite Avatar de Willy_k
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 541
    Par défaut
    Chez moi l'écriture $row['t1.data'] n'est pas refusée et affiche bien la valeur de la colonne....

  12. #12
    Membre éclairé
    Homme Profil pro
    Retraité Ing Electronique
    Inscrit en
    Mars 2004
    Messages
    369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Retraité Ing Electronique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2004
    Messages : 369
    Par défaut
    Merci willy

Discussions similaires

  1. requete multitable sur mysql
    Par tianet dans le forum Requêtes
    Réponses: 2
    Dernier message: 08/05/2007, 22h54
  2. [ASA] Problème sur requete ASA
    Par shadeoner dans le forum SQL Anywhere
    Réponses: 6
    Dernier message: 06/04/2005, 14h35
  3. [ASA] Problème sur requete
    Par shadeoner dans le forum SQL Anywhere
    Réponses: 9
    Dernier message: 30/03/2005, 15h59
  4. Calcul sur requete
    Par nicoolas dans le forum Access
    Réponses: 3
    Dernier message: 11/01/2005, 16h50
  5. idees sur requete a simplifier ???
    Par DaxTaz dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 05/07/2004, 09h42

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