题
我有一个采用以下形式的 SQL 查询:
UPDATE foo
SET flag=true
WHERE id=?
我还有一个 PHP 数组,其中包含 ID 列表。除了解析之外,实现此目的的最佳方法是什么,如下所示,...
foreach($list as $item){
$querycondition = $querycondition . " OR " . $item;
}
...并使用输出 WHERE
条款?
解决方案
这会实现同样的效果,但可能不会产生太多的速度提升,但看起来更好。
mysql_query("UPDATE foo SET flag=true WHERE id IN (".implode(', ',$list).")");
其他提示
您应该能够使用 IN 子句(假设您的数据库支持它):
UPDATE foo
SET flag=true
WHERE id in (1, 2, 3, 5, 6)
使用 IN 语句。提供以逗号分隔的键值列表。您可以使用轻松地做到这一点 implode
功能。
UPDATE foo SET flag = true WHERE id IN (1, 2, 3, 4, 5, ...)
或者,您可以使用条件:
UPDATE foo SET flag = true WHERE flag = false
或子查询:
UPDATE foo SET flag = true WHERE id IN (SELECT id FROM foo WHERE .....)
使用 join/implode 生成一个以逗号分隔的列表,最后得到:
UPDATE foo SET flag=true WHERE id IN (1,2,3,4)
除了 foreach 循环之外,我还没有见过其他方法可以做到这一点。
但是,如果 $list 以任何方式从用户处获取,您应该坚持使用准备好的语句,并且一次只更新一行(假设有人没有办法使用准备好的语句更新多行)。否则,你就会对 sql 注入持开放态度。
您可以使用 case 语句来进行更新,但您必须自己构建查询。
UPDATE foo
SET flag=CASE ID WHEN 5 THEN true ELSE flag END
,flag=CASE ID WHEN 6 THEN false ELSE flag END
WHERE id in (5,6)
where 可以省略,但可以避免全表更新。
VB.NET 代码:暗淡的 delimitedIdList as string = arrayToString(listOfIds)
暗淡的 SQL as string = " UPDATE foo SET flag=true WHERE id in (" + delimitedIdList + ")"
运行Sql(SQL)
如果您知道项目数量的限制,请使用“IN”子句,正如其他人建议的那样:
UPDATE foo SET flag=true WHERE id in (1, 2, 3, 5, 6)
但有一个警告是,根据您的数据库,子句中的元素数量可能会受到限制。例如,oracle 7 或 8(?)曾经有 256 项的限制(在以后的版本中显着增加)
如果您确实迭代列表,请使用事务,以便在其中一个更新失败时可以回滚