JeuWeb - Crée ton jeu par navigateur
PDO requete préparée WHERE IN - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : PDO requete préparée WHERE IN (/showthread.php?tid=5195)



PDO requete préparée WHERE IN - php_addict - 24-01-2011

bonsoir

je viens de m'apercevoir que les requêtes préparées PDO ont quand même quelques défauts notamment avec la clause WHERE IN (et sans parler de la pseudo portabilité des requetes selon les SBGD)...


ce code:


$liste='1,2,3';

$result=$connexion_mmorpg->query("SELECT id FROM joueur WHERE id IN($liste)");
$donnees=$result->fetchAll(PDO::FETCH_ASSOC);

print_r($donnees);

renvois (et c'est normal):

Array ([0] => Array ([id] => 1) [1] => Array ([id] => 2) [2] => Array([id] => 3))


alors que ce code:


$liste='1,2,3';

$query = "SELECT id FROM joueur WHERE id IN(:liste)";
$result = $connexion_mmorpg->prepare("$query");
$result->execute(array(':liste' => $liste));
$donnees=$result->fetchAll(PDO::FETCH_ASSOC);

print_r($donnees);


renvois :

Array( [0] => Array ([id] => 1))


avouez quand même que c'est un peu stupide non ? mais j'aimerais quand même bien savoir le pourquoi du comment...

ou alors je délire totalement ?

donc à éviter: WHERE id IN(:liste)


RE: PDO requete préparée WHERE IN - niahoo - 24-01-2011

Est-tu sûr qu'on peut directement passer un Array comme paramètre à execute()


RE: PDO requete préparée WHERE IN - php_addict - 24-01-2011

(24-01-2011, 10:53 PM)niahoo a écrit : Est-tu sûr qu'on peut directement passer un Array comme paramètre à execute()

oui... http://php.net/manual/fr/pdo.prepare.php


RE: PDO requete préparée WHERE IN - julp - 24-01-2011

Mouais, mais là c'est parce qu'il y a cast de la chaîne '1,2,3' en int (ce qui donne 1 - ça fonctionne comme en PHP, MySQL s'arrête au premier caractère qui n'est pas un chiffre).

Ça ne peut fonctionner ça (binder plusieurs valeurs en un paramètre). On aurait beau le prendre dans le sens que l'on veut, on en revient toujours à 1 paramètre = 1 valeur avec une requête préparée.

--

Pour être clair :
Sans la requête préparée, on obtient : SELECT id FROM joueur WHERE id IN(1, 2, 3)
Avec : SELECT id FROM joueur WHERE id IN('1, 2, 3')
C'est deux choses totalement différentes pour le SGBD.


RE: PDO requete préparée WHERE IN - php_addict - 24-01-2011

ok, merci pour l'explication

mais avouez que c'est quand même bien débile, pourquoi PDO ne filtre pas de la sorte: WHERE id IN('1','2','3')


RE: PDO requete préparée WHERE IN - julp - 25-01-2011

J'y ai déjà répondu et je ne vois pas en quoi c'est illogique. Comment PDO devrait-il savoir que la valeur ainsi bindée en représente en réalité plusieurs ? Comment saurait-il la redécouper ou lui faire subir je ne sais quel traitement ? Vous attendez de PDO des choses pour lequel il n'est pas prévu sans compter les problèmes que cela pourrait engendrer.

En réalité, j'ai écrit PDO, mais tel est le fonctionnement des requêtes préparées. Vous aurez le même résultat avec mysqli, sqlite3, oci8, etc.

C'est à vous, si vous voulez utiliser une requête préparée, de faire en sorte qu'à chaque valeur corresponde un paramètre.

PS : il me semble que seule l'API d'Oracle (ocilib ?) permet le bind de "tableaux" de valeurs. PHP/PDO ne peut donc pas apporter de solution au bind de plusieurs valeurs pour un même paramètre si ce n'est pas standardisé au niveau du SGBD et de son API.

Et une citation du wiki (RFC) de php.net :
Citation :Rejected Features
* Add support for “IN (?)” type prepared placeholders. ⇐ native prepared statement mandate that all placeholders only handle a single scalar value



RE: PDO requete préparée WHERE IN - php_addict - 25-01-2011

merci pour ces précisions


RE: PDO requete préparée WHERE IN - niahoo - 25-01-2011

C'est donc bien ce que je disais Tongue


RE: PDO requete préparée WHERE IN - php_addict - 25-01-2011

(25-01-2011, 10:00 AM)niahoo a écrit : C'est donc bien ce que je disais Tongue

:non: non, tu as dis:

(24-01-2011, 10:53 PM)niahoo a écrit : Est-tu sûr qu'on peut directement passer un Array comme paramètre à execute()

et la réponse est: oui on peut passer un array() à execte()

Wink


RE: PDO requete préparée WHERE IN - niahoo - 25-01-2011

allons, allons, ne sois pas de mauvaise foi, execute() prend un array comme paramètre, mais ton $liste n'est pas ce paramètre, et l'erreur venait bien du fait que tu envoyais un array comme valeur pour un bind.