query PHP Mysql PDO nombre de variables liées ne correspond pas au nombre de jetons



pdo query (2)

Salut j'ai regardé autour d'ici mais n'arrive pas à trouver une réponse trop mon problème.

C'est la première fois que j'utilise PDO et je suis donc complètement novice.

J'ai une charge de données divisée en 2 tables et je veux les fusionner en une, il y a d'autres façons de le faire, mais sans entrer dans les raisons compliquées pourquoi, j'essaie de le faire de cette façon ...

Je génère un jeu d'enregistrements de la table que je veux copier des données de

construire ma déclaration

l'exécuter en boucle

mais j'obtiens l'erreur suivante

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

Je suis passé à travers et triple vérifié j'ai la même quantité de variables, alors pourquoi "jetons ne correspondent pas, je ne sais pas", comme je l'ai dit est très nouveau à ce donc je suis probablement manquer quelque chose que le professionnel considérerait comme évident.

  • Il vaut probablement la peine de mentionner que je ne suis pas en train d'ajouter à chaque colonne du tableau, il y a d'autres colonnes mais je les ai laissées en dehors de la déclaration de préparation ... Voici mon code:

    //$dbh = new PDO($hostname_Seriously,  $DB_USER, $DB_PASSWORD);
    $dbh = new PDO('mysql:host=localhost;dbname=seriouslysoulful_summers', $username_Seriously, $password_Seriously);
    $stmt = $dbh->prepare("INSERT INTO records_rec (oldid_rec, firstname_rec, artist_rec, aside_rec, bside_rec, label_rec, condition_rec, genere_rec, price_rec, collection_rec, active_rec, info_rec, notes_rec, order_rec, alabelimage_rec, blabelimage_rec, asound_rec, bsound_rec, featured_rec, format_rec) 
    VALUES (:oldid_rec, :firstname_rec, :artist_rec, :aside_rec, :bside_rec, :label_rec, :condition_rec, :genere_rec, :price_rec, :collection_rec, :active_rec, :info_rec, :notes_rec, :order_rec, :alabelimage_rec, :blabelimage_rec, asound_rec, bsound_rec, :featured_rec, :format_rec)");
    $stmt->bindParam(':oldid_rec', $id);
    $stmt->bindParam(':firstname_rec', $firstname);
    $stmt->bindParam(':artist_rec', $artist);
    $stmt->bindParam(':aside_rec',$aside);
    $stmt->bindParam(':bside_rec',$bside);
    $stmt->bindParam(':label_rec',$label);
    $stmt->bindParam(':condition_rec',$condition);
    $stmt->bindParam(':genere_rec',$genere);
    $stmt->bindParam(':price_rec',$price);
    $stmt->bindParam(':collection_rec',$collection);
    $stmt->bindParam(':active_rec',$active);
    $stmt->bindParam(':info_rec',$info);
    $stmt->bindParam(':notes_rec',$notes);
    $stmt->bindParam(':order_rec',$order);
    $stmt->bindParam(':alabelimage_rec',$alabel);
    $stmt->bindParam(':blabelimage_rec',$blabel);
    $stmt->bindParam(':asound_rec',$asound);
    $stmt->bindParam(':bsound_rec',$bsound);
    $stmt->bindParam(':featured_rec',$featured);
    $stmt->bindParam(':format_rec',$format);
    $reccount = 0;
    //do{
    $id = $row_rs_original['id_prod'];
    $firstname = 
    mysql_real_escape_string($row_rs_original['firstname_prod']);
    $artist = mysql_real_escape_string($row_rs_original['artist_prod']);
    $aside = mysql_real_escape_string($row_rs_original['a_side_prod']);
    $bside = mysql_real_escape_string($row_rs_original['b_side_prod']);
    $label = mysql_real_escape_string($row_rs_original['label_prod']);
    $condition = mysql_real_escape_string($row_rs_original['condition_prod']);
    $genere = $row_rs_original['genre_prod'];
    $price = $row_rs_original['price_prod'];
    $collection = mysql_real_escape_string($row_rs_original['collection_prod']);
    $active = $row_rs_original['active_prod'];
    $info = mysql_real_escape_string($row_rs_original['info_prod']);
    $notes = mysql_real_escape_string($row_rs_original['notes_prod']);
    $order = $row_rs_original['order_prod'];
    $alabel = mysql_real_escape_string($row_rs_original['labelimage_A_prod']);
    $blabel = mysql_real_escape_string($row_rs_original['labelimage_B_prod']);
    $asound = mysql_real_escape_string($row_rs_original['soundfile_A_prod']);
    $bsound = mysql_real_escape_string($row_rs_original['soundfile_B_prod']);
    $featured = $row_rs_original['featured_prod'];
    $format = $row_rs_original['format_prod'];
    
    $stmt->execute();
    
        $reccount = $reccount +1;
    //} while ($row_rs_original = mysql_fetch_assoc($rs_original));
    echo($reccount." - records added...");

https://src-bin.com


Answer #1

Colons manquants

:blabelimage_rec, **:**asound_rec, **:**bsound_rec, :featured_rec, :format_rec

Answer #2

On dirait que Mark Baker a déjà répondu à votre question, mais je voulais ajouter quelques conseils qui m'ont beaucoup aidé.

PDO n'a pas besoin de mysql_escape_string
Tant que tout ce qui se passe dans votre requête qui traite de l'entrée de l'utilisateur utilise une instruction préparée (comme vous l'êtes ci-dessus), vous n'avez pas besoin d'échapper l'entrée avec mysql_real_escape_string [1].

// Don't worry about SQL injection since all of the user 
// defined inputs are being escaped by the PDO package
$sql = "INSERT INTO "
     .   "`users` "
     . "SET "
     .   "`name` = :name";

$query = $pdo->prepare($sql);
$query->bindParam(':name', $name);
$query->execute();

Mais soyez conscient que l'injection SQL est toujours possible si vous ne liez pas l'entrée de l'utilisateur:

// SQL injection can totally happen here
$sql = "INSERT INTO "
     .   "`users` "
     . "SET "
     .   "`name` = $name";

$query = $pdo->prepare($sql);
$query->execute();

[1] http://www.php.net/manual/fr/pdo.prepared-statements.php




Essayez de rendre votre SQL aussi court que possible
Pour les instructions SQL simples, plus il est court, plus il est facile à maintenir et moins vous risquez de commettre des erreurs. Vous pouvez utiliser une autre syntaxe INSERT [2]:

INSERT INTO 
  `users`
SET
  `name` = 'Steve';

est équivalent à:

INSERT INTO 
  `users`
  (
    `name`
  )
  VALUES
  (
    'Steve'
  );

Cela signifie que pour les grandes instructions comme la vôtre, vous pouvez effectivement la moitié de sa taille car vous n'avez pas besoin de répéter tous les noms de colonnes:

$sql  = "INSERT INTO "
      .   "`records_rec` "
      . "SET "
      .   "`oldid_rec`       = :oldid_rec, "
      .   "`firstname_rec`   = :firstname_rec, " 
      .   "`artist_rec`      = :artist_rec, " 
      .   "`aside_rec`       = :aside_rec, "
      .   "`bside_rec`       = :bside_rec, "
      .   "`label_rec`       = :label_rec, "
      .   "`condition_rec`   = :condition_rec, " 
      .   "`genere_rec`      = :genere_rec, "
      .   "`price_rec`       = :price_rec, "
      .   "`collection_rec`  = :collection_rec, "
      .   "`active_rec`      = :active_rec, "
      .   "`info_rec`        = :info_rec, "
      .   "`notes_rec`       = :notes_rec, "
      .   "`order_rec`       = :order_rec, "
      .   "`alabelimage_rec` = :alabelimage_rec, "
      .   "`blabelimage_rec` = :blabelimage_rec, "
      .   "`asound_rec`      = :asound_rec, "
      .   "`bsound_rec`      = :bsound_rec, "
      .   "`featured_rec`    = :featured_rec, "
      .   "`format_rec`      = :format_rec";

$dbh = new PDO(<info goes here>);
$stmt = $dbh->prepare($sql); 

// Bind your params here...

[2] http://dev.mysql.com/doc/refman/5.5/fr/insert.html




Ne faites vos déclarations SQL multi-ligne et jolie

J'ai commencé à formater mes instructions SQL pour être multi-lignées (comme ci-dessus) et depuis que j'ai eu moins d'erreurs comme ça. Cela prend beaucoup de place, mais je pense qu'à la fin ça vaut le coup. En faisant en sorte que tout s'aligne, les erreurs se détachent comme un pouce endolori.

Codage heureux!





prepared-statement