无法使用PDO更新行

时间:2011-07-26 11:29:25

标签: php mysql pdo

当我运行以下代码时:

  // Loop through each store and update shopping mall ID

  protected function associateShmallToStore($stores, $shmall_id) {

    foreach($stores as $store_id) {
      $sql .= 'UPDATE my_table SET fk_shmallID = :shmall_id WHERE id = :store_id';
      $stmt = $this->db->prepare($sql);
      $stmt->bindParam(':shmall_id', $shmall_id);
      $stmt->bindParam(':store_id', $store_id);
      $stmt->execute();
    }

  } 

我收到以下消息:
Warning: PDOStatement::execute() [pdostatement.execute]: SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters

我也试过以下但没有成功(没有$stmt->bindParam):
$stmt->execute( array($shmall_id, $store_id));

我不明白我做错了什么。

更新 我已经更新了我的代码,以反映我在源代码中实际得到的内容。这里不应该有任何拼写错误。

更新2
我尝试了这个,但我仍然收到相同的错误消息。

  protected function associateShmallToStore($stores, $shmall_id) {
    $i = 0;

    $sql .= "UPDATE sl_store ";

    foreach($stores as $store_id) {
      $i++;
      $sql .= 'SET fk_shmallID = :shmall_id, lastUpdated = NOW() WHERE id = :store_id_'.$i.',';  
    }

    $sql = removeLastChar($sql);
    $stmt = $this->db->prepare($sql);

    $stmt->bindParam(':shmall_id_'.$i, $shmall_id);

    $i = 0;
    foreach($stores as $store_id) {
      $i++;    
      $stmt->bindParam(':store_id_'.$i, $store_id);
    }

    $stmt->execute();
  }

这是SQL查询的输出:

UPDATE sl_store 
  SET fk_shmallID = :shmall_id, lastUpdated = NOW() WHERE id = :store_id_1,
  SET fk_shmallID = :shmall_id, lastUpdated = NOW() WHERE id = :store_id_2

更新3
我努力使用的代码是:

    foreach($stores as $store_id) {
      $sql = "UPDATE sl_store SET fk_shmallID = :shmall_id WHERE id = :store_id";
      $stmt = $this->db->prepare($sql);
      $stmt->bindParam(':shmall_id', $shmall_id);
      $stmt->bindParam(':store_id', $store_id);
      $res = $stmt->execute();
    } 

2 个答案:

答案 0 :(得分:4)

就像错误所说的那样,你有混合命名和位置参数:

  • :name(已命名)
  • :person_id(已命名)
  • ?(位置)

除此之外,您还有命名参数:person_id,但您绑定的是:id

这些是您的参数,我称之为P1P2P3

UPDATE my_table SET name = :name WHERE id = :person_id ?
                           ^ P1             ^ P2       ^ P3

这就是你绑定它们的地方:

  $stmt->bindParam(':name', $name); // bound to P1 (:name)
  $stmt->bindParam(':id', $person_id); // bound to nothing (no such param :id)

您可能希望将第二个参数绑定到:person_id,而不是绑定到:id,并删除最后一个位置参数(查询末尾的问号)。

此外,通过foreach循环的每次迭代都会向查询添加更多内容,因为您使用的是连接运算符而不是赋值运算符:

$sql .= 'UPDATE my_table SET name = :name WHERE id = :person_id ?';

您可能希望在.之前删除=

有关此内容的更多信息,请查看PDO手册中的Prepared statements and stored procedures页面。您将了解如何绑定参数以及命名参数和位置参数之间的差异。

所以,总结一下:

  1. 将SQL行替换为:

    $sql = 'UPDATE my_table SET name = :name WHERE id = :person_id';
    
  2. 将第二个bindParam()来电替换为:

    $stmt->bindParam(':person_id', $person_id);
    

答案 1 :(得分:0)

尝试:

$sql = 'UPDATE my_table SET name = :name WHERE id = :id';