【问题标题】:PDO updates only one row when used with placeholders与占位符一起使用时,PDO 仅更新一行
【发布时间】:2011-11-01 17:37:56
【问题描述】:

我有一个包含多个 id 的数组,我需要更新多个列。我为此使用 MySQL IN()。问题是当我使用下面的查询时它工作得很好。

public function available($value, $propertyId = array()) {
    $sth = $this->dbh->prepare('UPDATE properties p SET p.status = :status WHERE p.id IN('.implode(',',$propertyId).')');
    $sth->bindParam(':status',$value);
    return $sth->execute();
}

由于上述查询没有为第二个参数$propertyId 使用任何占位符,我认为这样做是错误的方法。但是当我在查询中使用命名或未命名的占位符时,它只会更新 1 行。例如下面的代码只更新一行。

//This will update only one row.
//Using Named Place Holder
public function available($value, $propertyId = array()) {
    $sth = $this->dbh->prepare('UPDATE properties p SET p.status = :status WHERE p.id IN(:propertyId)');
    $sth->bindParam(':status',$value);
    $sth->bindParam(':propertyId', implode(',', $propertyId));
    return $sth->execute();
}

或者

//Using Unnamed Place Holder.
public function available($value, $propertyId = array()) {
    $sth = $this->dbh->prepare('UPDATE properties p SET p.status = ? WHERE p.id IN(?)');
    return $sth->execute(array($value, implode(',', $propertyId)));
}

我尝试将数组转换为字符串并将其分配给如下变量。

public function available($value, $propertyId = array()) {
    $id = implode(',', $propertyId);
    $sth = $this->dbh->prepare('UPDATE properties p SET p.status = ? WHERE p.id IN(?)');
    return $sth->execute(array($value, $id));
}

即使这样也行不通。怎么了?我错过了什么?

谢谢

【问题讨论】:

  • AFAIK 参数化查询不能与列表IN (...) 一起使用,如果您没有使用占位符指定每个元素。 IN (?,?,?,? ...)。当 propertyId 仅包含整数值时,您的第一个查询就是要走的路。
  • 您可以在stackoverflow.com/questions/327274/…找到类似问题的解决方案
  • 只是为了支持第一条评论,Doctrine ORM 使用PDO 并为IN 查询生成(?,?,?,....)
  • @culrais,第一个查询对 SQL 注入安全吗?我不知道,但我认为那样做是不安全的。
  • @Ibrahim Azhar Armar,使用php.net/manual/en/pdo.quote.php 转义您在该查询中传递的所有数据(数组中的每个值,而不是内爆字符串),您将与使用 pdo::prepare/bind_param 一样安全, 但当然会产生更多的流量到 SQL 服务器 - 每个 eascape 调用都应该是 MySql 调用。

标签: php mysql pdo


【解决方案1】:

你可以做这样的事情,希望它有所帮助。

public function available($value, $propertyId = array()) {
    $id_placeholders = implode(',', array_fill(0, count($propertyId), '?'));
    $sth = $this->dbh->prepare('UPDATE properties p SET p.status = ? WHERE p.id IN('.$id_placeholders.')');
    return $sth->execute(array_merage(array($value), $propertyId));
}

【讨论】:

    猜你喜欢
    • 2016-07-10
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 2011-01-26
    • 2012-01-23
    相关资源
    最近更新 更多