8795 sujets

Développement web côté serveur, CMS

Bonjour

J'ai un problème pour utilisé la clause IN avec PDO.

Voici mon code


<?php

  $query = $this->_pdo->prepare('SELECT * FROM personnel '.
                                       'WHERE nom LIKE :queryString '.
                                       'AND statut IN ( :statut ) '.
                                       'ORDER BY nom ASC');
        
         $query->execute(array(':queryString' => $queryString.'%', ':statut' =>  $statut));

?>


Je précise que je passe à IN une chaine de caractère de la forme 'data1', 'data2', 'data3'

Est-ce que quelqu'un sait comment faire marche les requêtes préparé avec IN ?

Merci d'avance
Modifié par ArnaudS (25 Aug 2009 - 13:41)
Salut,

Dans ta variable PHP, tes données sont au format texte, on est d'accord. Mais quand tu les insères comme ça, elles ne sont pas au format texte en MySQL. Il te manque les guillemets dans ta requête. Mais pas deux guillemets qui entourent l'ensemble du texte, des guillemets autour de chaque valeur.
Modifié par Agylus (25 Aug 2009 - 09:09)
Oui c'est entendu

Je passe un argument de cette forme


'\'data1\', \'data2\', \'data3\''


à la méthode qui est charger d'effectuer la requête.

donc mysql le vois bien comme ça

 'data1', 'data2', data3'


Ou alors j'ai loupé quelque chose Smiley rolleyes
Heu, on peut plutôt voir le contenu de ta variable $statut tel qu'il est dans ton code ?
Modifié par Agylus (25 Aug 2009 - 09:20)
Voici mon code

Tout d'abbord l'appelle à la méthode


 $personnelSearch = $ueDao->selectPersonnelByChars($cleanQueryString, '\'responsable\', \'auteur\', NULL');



et le code de la méthode :



 function selectPersonnelByChars($queryString, $statut)
     {

         
         $query = $this->_pdo->prepare('SELECT * FROM personnel '.
                                       'WHERE nom LIKE :queryString '.
                                       'AND statut IN ( :statut ) '.
                                       'ORDER BY nom ASC');
        
         $query->execute(array(':queryString' => $queryString.'%', ':statut' =>  $statut));
         
         $result = $query->fetchAll(PDO::FETCH_OBJ);

         return $result;

     }



Une petite précision la requête marche dans phpMyAdmin quand je remplace les variable par des valeurs en dures
Oui, c'est normal. Tu n'as qu'un niveau d'échappement. Donc quand ton code est interprété ça donne :

$query = $this->_pdo->prepare('SELECT * FROM personnel '.
                                       'WHERE nom LIKE :queryString '.
                                       'AND statut IN ( 'responsable', 'auteur', NULL ) '.
                                       'ORDER BY nom ASC');

Comme tu peux le voir, tes apostrophes dans le IN de statut coupent ta chaine PHP.

Le mieux serait que tu fasses quelque chose comme :

$tStatut = array( '"responsable"', '"auteur"', 'NULL' );
$personnelSearch = $ueDao->selectPersonnelByChars($cleanQueryString, $tStatut);

...

$query->execute(array(':queryString' => $queryString.'%', ':statut' =>  implode(', ', $tStatut)));

Modifié par Agylus (25 Aug 2009 - 09:53)
Merci pour ta réponse.

C'est vrai que c'est une erreur un peu bête Mais HELAS.

Ca ne marche toujous pas.

Quand j'enlève la clause in tout marche.

Quand je met la clause in plus rien ne marche Smiley ohwell
Et si tu regardais le SQL généré pour qu'on sache à quoi s'en tenir ?
Et si tu supprimais le NULL pour voir ce que ça donne ?
Supprimer le NULL n'a rien changé.

Par contre comment fais-tu pour voir le SQL générer ?

j'ai inclue


var_dump($query);


et j'obtiens la trace suivante

object(PDOStatement)#4 (1) { ["queryString"]=> string(94) "SELECT * FROM personnel WHERE nom LIKE :queryString AND statut IN ( :statut ) ORDER BY nom ASC" }
Bien sur

Voici mon code :

L'appel de la méthode


 $statutArray = array('"responsable"', '"auteur"');
 $personnelSearch = $ueDao->selectPersonnelByChars($cleanQueryString, $statutArray);


et la méthode :


    function selectPersonnelByChars($queryString, $statutArray)
     {
         $statut = implode(', ',$statutArray);
        
         $query = $this->_pdo->prepare('SELECT * FROM personnel '.
                                       'WHERE nom LIKE :queryString '.
                                       'AND statut IN ( :statut ) '.
                                       'ORDER BY nom ASC');
                

         $query->execute(array(':queryString' => $queryString.'%', ':statut' => $statut));
         
               
          
         $result = $query->fetchAll(PDO::FETCH_OBJ);

         return $result;

     }

Hum .. J'ai envie de te dire que tu as le même problème pour ta variable $queryString non ? Smiley lol
Modifié par Agylus (25 Aug 2009 - 12:14)
Et non justement. Je n'ai aucun problème avec la variable $queryString.

Ca aurait été simple si les deux variable se comportait de la même façon Smiley confus

C'est pour ça que je pense qu'il doit y avoir une astuce de sioux pour gérer la clause IN avec PDO.
Ca y est, enfin! A force de bidouille j'ai fini par trouver.

Merci à toi Agylus

En relisant la doc de php de la méthode PDO::prepare une phrase m'a interpellé :

a écrit :
Vous ne pouvez associer plusieurs valeurs à un seul marqueur de nom entrant, par exemple, la clause IN() d'une requête SQL.


Alors à quoi bon s'acharner ? Smiley biggol

Voici le code final si ça peut aider

Appel de la méthode :



$statutArray = array('"responsable"', '"auteur"', 'NULL');
$personnelSearch = $ueDao->selectPersonnelByChars($cleanQueryString, $statutArray);



Et le code de la méthode


 function selectPersonnelByChars($queryString, $statutArray)
 {

        $statut = implode(', ',$statutArray);
 
         $query = $this->_pdo->prepare('SELECT * FROM personnel '.
                                       'WHERE nom LIKE :queryString '.
                                       'AND statut IN ('.$statut.') '.
                                       'ORDER BY nom ASC');

         $query->execute(array(':queryString' => $queryString.'%'));
                
         $result = $query->fetchAll(PDO::FETCH_OBJ);

          return $result;

     }



Seul petit problème la variable $statut n'est pas protégé. Mais quoi qu'il arrive cette méthode n'est appeller qu'avec des paramètres en dur (pas de récupération de données utilisateurs).

Alors est-ce si grave ?