Partage
  • Partager sur Facebook
  • Partager sur Twitter

Erreur PDO SQLSTATE[HY093]

Sujet résolu
19 décembre 2009 à 11:22:45

Bonjour :) ,

j'ai une erreur tenace où j'ai beau relire ma requête dans tous les sens, aucun problème ne semble apparaitre...

Voici l'erreur:

Citation

Warning: PDOStatement::execute() [pdostatement.execute]: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in C:\wamp\www\Projet_X-100\serveur_1\class\alliance.php on line 154



<?php
// alliance_droit
$sql_alliance_droit = $this->bdd->prepare('
INSERT INTO alliance_droit
(id_droit, id_rang, id_alliance, voir_membre, voir_online, envoyer_message, gestion_defcon, gestion_txt, gestion_rang, gestion_recrutement)
VALUES ("", :id_rang,:$id_alliance,"0", "0", "0", "0", "0", "0", "0")');


$sql_alliance_droit->execute(array(':id_alliance' => $id_alliance, ':id_rang' => $id_rang));


sachant que $id_alliance, et $id_rang sont défini et sont valides...

Une idée ?

PS: la ligne 154 est ici la ligne 9.
  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
19 décembre 2009 à 11:44:47

Ligne 6 : tu a mis un $ de trop dans :$id_alliance ;)
  • Partager sur Facebook
  • Partager sur Twitter
19 décembre 2009 à 11:51:21

Merci! :)

j'ai juste du relire ce passage 20 à 30 fois pourtant...
  • Partager sur Facebook
  • Partager sur Twitter
24 mars 2010 à 23:34:44

Je me permets de poster dans ce sujet car j'ai exactement la même erreur, mais je pense que la raison est différente.
Voici ma fonction de création:
public function create(Athlete $athlete) {

        $query = $this->db->prepare('INSERT INTO athletes (name,firstname,pseudo,level,mobile,fix,pass,avatar,login,email,birth,class_id,
            hobbies,description,signature, facebook) VALUES (:name,:firstname,:pseudo,:level:,mobile,:fix,:pass,:avatar,:login,:email,:birth:,class_id,
            :hobbies,:description,:signature, :facebook)');

        $query->execute( array(
                'name'=> $athlete['name'],
                'firstname'=> $athlete['firstname'],
                'pseudo'=> $athlete['pseudo'],
                'level'=> $athlete['level'],
                'mobile'=> $athlete['mobile'],
                'fix'=> $athlete['fix'],
                'pass'=> $athlete['pass'],
                'login'=> $athlete['login'],
                'email'=> $athlete['email'],
                'birth'=> $athlete['birth'],
                'class_id'=> $athlete['class_id'],
                'hobbies'=> serialize($athlete['hobbies']),
                'description'=> $athlete['description'],
                'signature'=> $athlete['signature'],
                'facebook' => $athlete['facebook'],
                'avatar' => $athlete['avatar']
        ));
    }


Et voici ce que je lui passe comme paramètre:
$values = array (
                    'name'=> $_POST['name'],
                    'firstname'=> $_POST['firstname'],
                    'pseudo'=> '',
                    'level'=> 5,
                    'mobile'=> '',
                    'fix'=> '',
                    'pass'=> '',
                    'login'=> '',
                    'email'=> '',
                    'birth'=> '',
                    'class_id'=> $_POST['class'],
                    'hobbies'=> '',
                    'description'=> '',
                    'signature'=>'',
                    'facebook' => '',
                    'avatar' => 'avatar\\default.jpg'
            );

            AthleteManager::getInstance()->create( new Athlete($values) );

J'ai checké les noms tout m'a l'air correct...
Merci de votre aide!
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:02:03

Tu n'as mis aucun ":" dans ton array là est toute la différence name != :name
Sinon j'vous conseille à tous les 2 la méthode bindValue ou bindParam qui va rendre lisible votre code et sa sécurité (puisqu'on doit spécifier le type de donnée)
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:07:58

J'aime pas le plagia mais bon...Look, j'ai exactement respecter la structure du code:
<?php
$req = $bdd->prepare('INSERT INTO jeux_video(nom, possesseur, console, prix, nbre_joueurs_max, commentaires) VALUES(:nom, :possesseur, :console, :prix, :nbre_joueurs_max, :commentaires)');
$req->execute(array(
	'nom' => $nom,
	'possesseur' => $possesseur,
	'console' => $console,
	'prix' => $prix,
	'nbre_joueurs_max' => $nbre_joueurs_max,
	'commentaires' => $commentaires
	));

echo 'Le jeu a bien été ajouté !';
?>
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:10:19

Et si tu regardes sa requête, tu n'y verras aucun ":", ceci explique cela. CQFD.
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:14:22

Alors attends, paske je sais que je suis bigleux mais à ce point là...
$req = $bdd->prepare('INSERT INTO jeux_video(nom, possesseur, console, prix, nbre_joueurs_max, commentaires) VALUES(:nom, :possesseur, :console,:prix, :nbre_joueurs_max, :commentaires)');
Y'a bien des ':' là nan?
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:15:42

Ah bah oui, je n'ai pas regardé au bon endroit, dans ce cas c'est une erreur du tuto.
Tu dois rajouter les : pour associer les marqueurs à une variable.

Sinon j'le répète mais la méthode bindValue est bien plus lisible qu'un array et sécurisera les données.
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:18:48

Alors là je doute, car ce code fonctionne:
<?php         
$query = $this->db->prepare('UPDATE athletes SET name = :name,firstname = :firstname, pseudo = :pseudo,level = :level,mobile = :mobile,fix = :fix,
            pass = :pass,avatar = :avatar,login = :login, email = :email, birth = :birth, class_id = :class_id, hobbies = :hobbies, description = :description,
            signature = :signature, login = :login WHERE id = :id');

        $query->execute( array(
                'name'=> $athlete['name'],
                'firstname'=> $athlete['firstname'],
                'pseudo'=> $athlete['pseudo'],
                'level'=> $athlete['level'],
                'mobile'=> $athlete['mobile'],
                'fix'=> $athlete['fix'],
                'pass'=> $athlete['pass'],
                'avatar'=> $athlete['avatar'],
                'login'=> $athlete['login'],
                'email'=> $athlete['email'],
                'birth'=> $athlete['birth'],
                'class_id'=> $athlete['class_id'],
                'hobbies'=> serialize($athlete['hobbies']),
                'description'=> $athlete['description'],
                'signature'=> $athlete['signature'],
                'facebook'=> $athlete['facebook'],
                'id'=> $athlete['id']
        ));?>


J'ai testé pour avoir bonne conscience et ça ne marche pas... :(
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:22:19

Faudrait savoir, ça fonctionne ou ça ne fonctionne pas ?
un marqueur possède un nom et commence par :
J'peux pas t'aider plus si tu ne veux pas faire ce que l'on te dit de faire.

Et de façon, ce topic n'est pas le tien, tu devrais en créer un à toi.
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:27:48

Je comprends que tu veuilles avoir raison, et moi tort ( ce qui est déjà fait soit disant en passant) mais prends le temps de lire et de comprendre ce que j'écris... Pour ce qui est de bindValue, je ne vois pas l'intêret de sécuriser mes données vu la faible importance de celles-ci, de plus je déteste voir la même ligne de code apparaitre plusieurs fois...Je préfère l'utilisation d'un array tout joli tout plein et tout simple! :)

P.S: Pour ce qui est d'écrire un autre topic, très bien, mais pourquoi créer deux topics avec exactement la même problématique? Surtout, que si j'en créer un, beaucoup de personnes me renverront sur ce lien, donc autant tout de suite poster ici...
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:32:37

Tu vois pas l'intérêt de sécuriser ? J'ai envi de dire, bah amuse-toi le jour où tu te fais hacker ton site.

En attendant tu ne réponds pas à la question, tu dis dans un premier temps que le code fonctionne, et par la suite tu dis qu'il ne fonctionne pas.

Et je le répète les marqueurs de ton array n'existe pas dans ta requête.
Regarde un peu la requête de l'auteur du sujet tu y verras les ":" dans son array et bizarrement son code fonctionne.
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:39:27

Bon je vais te mettre les choses au clair:

Citation : WarriorDog

J'ai testé pour avoir bonne conscience et ça ne marche pas... :(



En réponse à:

Citation : Chipie

Tu dois rajouter les : pour associer les marqueurs à une variable.


  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:43:23

Si si ils y sont, tu ne les as pas vu c'est tout.
Sinon j'y pense mais ta fonction elle a accès aux variables du tableau $athletes ?
Y'aurait pas un souci de portée de variable ?
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:45:34

Bah normalement oui, ma fonction UPDATE (celle que j'ai ci-joint plus haut) marche très bien, donc je vois pas pourquoi celle-ci ne marcherai pas...
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:47:09

Bah écoute, à ce compte-là t'as plus vite fait de créer ton propre sujet de bien tout exposer les codes.
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 0:49:37

C'est pas nécessaire d'ajouter les deux-points, PDO est capable de remplacer les variables quand même. Ainsi, tout ça retourne le même truc :

<?php
            $statement = $pdo->prepare("SELECT * FROM test WHERE id=:id");

            $statement->execute(array('id' => 50));
            $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
            echo '<pre>'; print_r($rows); echo '</pre>';
            $statement->closeCursor();

            $statement->bindValue('id', 50, PDO::PARAM_INT);
            $statement->execute();
            $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
            echo '<pre>'; print_r($rows); echo '</pre>';
            $statement->closeCursor();


            $statement->execute(array(':id' => 50));
            $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
            echo '<pre>'; print_r($rows); echo '</pre>';
            $statement->closeCursor();

            $statement->bindValue(':id', 50, PDO::PARAM_INT);
            $statement->execute();
            $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
            echo '<pre>'; print_r($rows); echo '</pre>';
            $statement->closeCursor();
  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 1:08:43

Bon j'ai trouvé...Il suffit de regarder attentivement cette ligne:
"...,:level:,mobile,:fix,:pass,:avatar,:login,:email,:birth:,..."

Certains ":" n'ont pas leur place...


  • Partager sur Facebook
  • Partager sur Twitter
25 mars 2010 à 1:10:49

Je viens de voir un truc, tu as 2x login = :login dans ta requête ce n'est probablement pas source de bug mais ce n'est pas très utile
  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2011 à 23:55:21

J'ai eu le même problème mais pour une autre raison encore...

Pour ceux qui tomberont sur ce forum je tiens à préciser que les tirets - (appelés "dash" je crois) ne sont apparemment pas bien compris par PDO::prepare() et PDO::execute(), j'ai dû les enlever pour que le code marche, exemple :

"...mot-cle=:num_mot-cle..." est devenu "...mot-cle=:num_motcle..."

  • Partager sur Facebook
  • Partager sur Twitter
3 août 2011 à 22:59:29

Bonjour, j'ai eu erreur au niveau de mon code et là je me retrouve coincé.

Voila l'erreur:

Citation

Erreur : SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens



Et voila le code :-° :

<?php
try
{
 $pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
 $bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '', $pdo_options);

$req = $bdd->prepare('INSERT INTO Inscription(ID, Nom, Prenoms, Pseudo, Âge, Mot de passe, Adresse e-mail) VALUES(" ", :Nom, :Prenoms, :Pseudo, :Âge, :Mot de passe, :Adresse e-mail)');
$req->execute(array(
	'Nom' => $_POST['nom'],
	'Prenoms' => $_POST['Prenom'],
	'Pseudo' => $_POST['pseudo'], 
	'Âge' => $_POST['Age'],
	'Mot de passe' => $_POST['Mot'],
	'Adresse e-mail' => $_POST['E-mail']	
	
	              ));
echo "L'inscription s'est bien deroulé !";
$req->closeCursor();
}
catch(Exception $e)
{
    die('Erreur : '.$e->getMessage());
}
 ?>


Et aussi si vous pouvez m'aidez a intégrer l'heure dans la base de donnée avec ce code ca serait pas mal :lol: .
Merci d'avance.
  • Partager sur Facebook
  • Partager sur Twitter
31 octobre 2011 à 15:33:12

Citation : Zazou

Sinon j'le répète mais la méthode bindValue est bien plus lisible qu'un array et sécurisera les données.



Plus lisible : tout dépend de comment tu indente ton code :

array(':objectId' => $this->_postImportId,
      ':termTaxonomyId' => $importTermTaxonomyId
);

Je trouve pas que sa soit illisible ^^

Sinon pour le coter sécurisation des données :

Il me semble que c'est la fonction execute qui vas les sécuriser et pas la fonction bindParam mais j'en suis pas certain (à vérifier)

Sinon pour AttouX :

Citation : AttouX

Et aussi si vous pouvez m'aidez a intégrer l'heure dans la base de donnée avec ce code ca serait pas mal :lol: .



Le mieux reste d'inserer un Timestamp dans la base que tu reconvertit en date en PHP.
  • Partager sur Facebook
  • Partager sur Twitter