【问题标题】:PHP Mysql PDO number of bound variables does not match number of tokens [closed]PHP Mysql PDO绑定变量数与令牌数不匹配[关闭]
【发布时间】:2012-02-17 15:47:34
【问题描述】:

我环顾四周,但似乎找不到我的问题的答案。

这是我第一次使用 PDO,所以完全是新手。

我将大量数据拆分为 2 个表并希望将它们合并到一个表中,还有其他方法可以做到这一点,但没有深入了解我尝试这样做的复杂原因......

我生成了一个要从中复制数据的表的记录集

构建我的陈述

循环运行

但我收到以下错误

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

我已经检查了三次,我有相同数量的变量,所以为什么“令牌不匹配我不知道”,就像我说的那样,我对此很陌生,所以可能遗漏了一些专业人士认为显而易见的东西。

  • 可能值得一提的是,我没有添加到表中的每一列,还有其他列,但我将它们排除在准备好的语句之外...... 这是我的代码:

    //$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...");
    

【问题讨论】:

    标签: php mysql pdo prepared-statement


    【解决方案1】:

    看起来 Mark Ba​​ker 已经回答了您的问题,但我想添加一些对我有很大帮助的提示。

    PDO 不需要mysql_escape_string
    只要处理用户输入的查询中的所有内容都使用准备好的语句(就像您在上面一样),您就不需要使用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();
    

    但请注意,如果您不绑定用户输入,SQL 注入仍然是可能的:

    // 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/en/pdo.prepared-statements.php




    尽量缩短 SQL 长度
    对于简单的 SQL 语句,越短越容易维护,出错的可能性也就越小。您可以使用另一种 INSERT 语法[2]:

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

    相当于:

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

    这意味着对于像你这样的大语句,你可以有效地减半它的大小,因为你不需要重复所有的列名:

    $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/en/insert.html




    让您的 SQL 语句多行且美观

    我开始将我的 SQL 语句格式化为多行(如上),自从我遇到这样的错误以来,我的错误就少了很多。它确实占用了很多空间,但我认为最终它是值得的。通过使所有内容都对齐,它会使错误像拇指一样突出。

    编码愉快!

    【讨论】:

    • 我对此赞不绝口!
    【解决方案2】:

    缺少冒号

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

    【讨论】:

      猜你喜欢
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      相关资源
      最近更新 更多