0

我有一个mysql表,里面有很多数据。此表中的所有行都需要以一种在纯 SQL 中不易表达的方式修改一个字段。

我希望能够逐行遍历表格,并一一更新所有条目。但是要做到这一点,我会做类似的事情:

$sql = "SELECT id,value FROM objects";
foreach ($dbh->query($sql) as $row)
{
    $value = update_value( $row['value'] );
    $id = $row['id'];
    $update_sql = "UPDATE objects SET value='$value' WHERE id=$d";
    $dbh->query( $update_sql );
}

这会做坏事吗?(除了可能很慢?)

澄清:特别是我担心第一次选择使用游标,而不是在foreach中一次点击检索所有数据,然后我不知道循环内更新导致游标失效。如果有一些规则,比如“不要在用另一个游标扫描同一个表时更新它”,它很可能只会出现在大表上,所以我执行一个小测试用例几乎没有用。

如果有人可以向我指出这样做是可以的文档,而不是以这种方式工作的特定问题,那也很好。

4

2 回答 2

0

似乎您一开始就有两个选择:

  1. (直截了当):在开始循环之前使用类似 'fetchAll' 来获取第一个查询的所有结果。这将帮助您避免光标重叠。
  2. (更模糊):将其更改为使用存储函数(代替“update_value”),这样您就可以将两个查询变成一个“更新对象集值=some_function(id)”

根据此操作的大小和持续时间,您可能需要事先锁定所有内容。

于 2013-03-21T12:54:14.457 回答
0

单个查询的结果是一致的,所以更新不会影响它。要牢记:

  1. 使用准备好的语句;它将减少您的进程和数据库之间的流量,因为每次只传输值而不是整个查询。

  2. 如果您担心其他进程同时运行,您应该使用事务和适当的锁定,例如

    // transaction started
    SELECT id,value 
    FROM objects 
    LOCK IN SHARE MODE
    
    // your other code
    
    // commit transaction
    
于 2013-03-21T13:02:07.970 回答