gpt4 book ai didi

Drupal 7 |使用 db_update 更新多行

转载 作者:行者123 更新时间:2023-12-01 00:58:27 24 4
gpt4 key购买 nike

我有一个像

Array (
[1] => 85590762,22412382,97998072
[3] => 22412382

)

其中 key 是 item_id 而 value 是我需要针对项目更新的列的值。我可以在循环中使用 db_update,但由于性能原因,我想避免这种策略。我想在单个数据库调用中更新所有行。我认为也使用 db_query 不是一个好主意。那么有没有办法使用 db_update 来更新这些行呢?

根据上面的数据,标准的mysql查询会像
update items set sold= 1, users = '85590762,22412382,97998072' Where item_id = 1; 
update items set sold = 1, users = '22412382' Where item_id = 3;

最佳答案

不幸的是,你不能这样做。目前并且可能在该功能中,将不支持使用一个 db_update 更新具有不同值的不同行上的(多个)值。

如果您的数据是这样的:

$for_update = array(
1 => "85590762,22412382,97998072",
3 => "22412382",
);

你可以这样做:

案例1:创建一个循环并在每次更新函数时调用:
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 相同 +
优点:如果你需要保持一致,你可以回滚你的数据,你只写一次数据到驱动器<所以 sql 只“一次”做 IO,大量的数据库连接/流量

案例 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 注入(inject),所以它会阻塞。但是你可以设置这个,但不推荐。 ( PDO support for multiple queries (PDO_MYSQL, PDO_MYSQLND))

13-05-2019 编辑:
顺便说一句,几个月前我对中等数据集进行了一些性能测量,以通过 db_select 查询一些数据。和 db_query .这些性能的大小是:在你运行一个 db_select , 你可以运行两个 db_query .这也适用于 db_updatedb_query .测试用一个简单的 SELECT 查询了一些列, 没有 JOINS ,没有花哨的花花公子,只有两个条件。当然,测量还包含/包括建立这些查询所需的时间(在这两种情况下)。但是请注意,Drupal 编码标准要求使用 db_update , db_delete , db_merge正常修改时,仅“允许” db_query而不是 db_select手术。

关于Drupal 7 |使用 db_update 更新多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25646525/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com