很遗憾,您不能这样做。目前并且可能在该功能中,将不支持使用一个 db_update 更新具有不同值的不同行上的(多个)值。
如果你的数据是这样的:
$for_update = array(
1 => "85590762,22412382,97998072",
3 => "22412382",
);
你可以这样做:
CASE 1:创建循环,每次调用update函数:
foreach ($for_update as $key => $value) {
$fields = array('sold' => 1, 'users' => $value);
db_update('items')->fields($fields)->condition('item_id', $key, '=')->execute();
}
优点:其他模块可以挂接到您的查询中,可以支持多个数据库驱动程序
缺点:对象初始化很慢,数据库连接/流量很多
案例2:使用db_query()会更快...
...因为在这种情况下没有对象实例化/操作,这有点昂贵和其他转换。 (即:https://drupal.stackexchange.com/questions/129669/whats-faster-db-query-db-select-or-entityfieldquery)
foreach ($for_update as $key => $value) {
db_query("UPDATE items SET sold = :sold, users = :users WHERE item_id = :item_id",
array(':sold' => 1, ':users' => $value, ':item_id' => $key)
);
}
优点:没有对象初始化和操作
缺点:其他模块无法挂接到您的查询中,您的代码可能会在不同的数据库驱动程序下中断,大量的数据库连接/流量
案例3:也可以使用事务
这在某些情况下可以提高你的表现。
$transaction = db_transaction();
try {
foreach ($for_update as $key => $value) {
$fields = array('sold' => 1, 'users' => $value);
db_update('items')->fields($fields)->condition('item_id', $key, '=')->execute();
}
}
catch (Exception $e) {
$transaction->rollback();
watchdog_exception('my_type', $e);
}
注意:事务主要用于当你想要一切或什么都不想要的时候。但是使用一些 DB 驱动程序,您可以优化 COMMIT 命令。
如果是 1,你会得到这样的结果:
UPDATE items SET sold = 1, users = '85590762,22412382,97998072' WHERE item_id = 1;
COMMIT;
UPDATE items SET sold = 1, users = '22412382' WHERE item_id = 3;
COMMIT;
通过交易,您可以执行以下操作:
UPDATE items SET sold = 1, users = '85590762,22412382,97998072' WHERE item_id = 1;
UPDATE items SET sold = 1, users = '22412382' WHERE item_id = 3;
COMMIT;
使用 COMMIT,您可以将数据写入最终位置(长期存储,在此之前,它只是内存中的某个位置或临时位置)。当您使用回滚时,您会放弃这些更改。至少我是这样理解的。 (即,当我使用 sqlite 时,我得到了性能提升。)
与案例 1 或 2 相同 +
优点:如果你需要保持一致,你可以回滚你的数据,你只写一次数据到驱动器
案例 4:或者您可以为此构建一个 sql 语句:
$ids = array();
$when_then = "";
foreach ($for_update as $key => $value) {
$ids[] = $key;
$when_then .= "WHEN $key THEN '$value' ";
}
db_query("UPDATE items
SET sold = 1, users = CASE item_id
$when_then
ELSE users
END
WHERE item_id IN(:item_ids)", array(':item_ids' => $ids));
这可能是从这里开始最快的方式。
注意:$when_then 变量不包含最佳解决方案,最好使用参数或转义不安全数据。
优点:在您的服务器和 sql 之间只有一个请求和较少的冗余数据,一个更大的 sql 查询比很多小的查询更快
缺点:其他模块无法挂接到您的查询中,您的代码可能会在不同的数据库驱动程序下中断
另外请注意,在(我认为)PHP 5.3 之后,默认情况下您不能在 db_query 或 PDO 中运行多个语句,因为它可能是 SQL 注入,所以它会阻塞。但是你可以设置这个,但不推荐。 (PDO support for multiple queries (PDO_MYSQL, PDO_MYSQLND))
13-05-2019 编辑:
顺便说一句,几个月前我对中等数据集进行了一些性能测量,以通过db_select 和db_query 查询一些数据。这些性能的大小是:在你运行一个db_select 下,你可以运行两个db_query。这也适用于db_update 和db_query。测试用简单的SELECT 查询了一些列,没有JOINS,没有花哨的花花公子的东西,只有两个条件。当然,测量还包含/包括建立这些查询所需的时间(在这两种情况下)。但请注意,Drupal 编码标准要求在正常修改时使用db_update、db_delete、db_merge,仅“允许”db_query 而不是db_select 操作。