用一次查询更新多行数据

4

如何一次性更新数百行?

例如: UPDATE table SET a = ? WHERE b = ? AND c = 1

但是需要更新许多行,? 参数为数组...

我阅读了这个答案,但它使用了CASE,我不认为我能这样做...


目前我有类似于这样的内容:

foreach($values as $key => $value)
  $res = $pdo->prepare('UPDATE table SET a = ? WHERE b = ? AND c = 1');
  $res->execute(array($value, $key));
}

为什么你不能使用CASE语句? - DarkAjax
1
一个带有数组内容的实际例子会很有帮助。 - user557846
庞大不一定意味着错误,否则就只能循环。 - user557846
djacobson,确切地说(不是相同的值,每条记录都将具有与b值相关联的不同值)。我现在正在使用foreach循环来完成这个操作,但我想用只有mysql的更短的方式来完成此操作。 - Alex
4
建议在循环外调用prepare()方法。 - chelmertz
显示剩余4条评论
3个回答

8
要在单个查询运行中完成此操作,您需要使用CASE以编程方式组装参数。 SQL不支持变参准备语句,只能将简单值参数化。
或者,定义一个仅接收一行数据的语句,并循环运行查询。重复执行是准备语句设计用于此类情况的方式。
try {
    $query = $db->prepare('UPDATE table SET a = ? WHERE b = ? AND c = 1');
    foreach ($as as $i => $a) {
        $query->execute(array($a, $bs[$i]));
    }
} catch (PDOException $e) {
    ...
}

你能否创建一个case语句并仍然利用预处理语句来防止SQL注入,还是必须像以前一样转义每个输入? - JM4
@JM4:这取决于您需要参数化的内容。预处理语句类似于函数,但只能对值(而不是列名等)进行参数化。只要您只需要这些,那么预处理语句就可以正常工作。然而,我建议采用类似于我的示例代码的解决方案,因为它总体上更简单。与函数不同,预处理语句的参数通常无法重复使用,因此您将不得不拥有单独的参数并重复值,这很容易出错。 - outis

4
请按照提供的链接使用CASE方法,但是要根据所需值动态构建查询。很可能,您将使用类似于您已经执行的for循环来构建它,但最终只会有一个查询,而不是在每次迭代中查询数据库。

唯一的缺点是(这也是我自己的建议),您无法像单行语句那样使用预处理语句来转义输入的数据。 - JM4

2

另一种方法是将您的键值对一次性全部插入到临时表中,然后执行以下操作:

UPDATE table t
SET t.a = (SELECT p.a FROM tmp p WHERE p.b = t.b)
WHERE t.b IN (SELECT p.b FROM tmp p) AND t.c = 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接