Drupal 7 |使用db_update更新多行
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Drupal 7 |使用db_update更新多行相关的知识,希望对你有一定的参考价值。
我有一个类似的数组
Array (
[1] => 85590762,22412382,97998072
[3] => 22412382
)
其中key是item_id,value是我需要针对项更新的列的值。我可以在循环中使用db_update但我想避免这种策略由于性能。我想更新单个db调用中的所有行。同样使用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();
}
优点:其他模块可以挂钩查询,可以支持多个DB驱动程序 缺点:对象初始化很慢,很多数据库连接/流量
情况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查询比很多小的查询更快 缺点:其他模块无法挂钩查询,您的代码可能会在不同的DB驱动程序下中断
另请注意,在(我认为)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 Coding Standard要求通常使用db_update
,db_delete
,db_merge
,只允许'允许'db_query
而不是db_select
操作。
Using BULK UPDATE you can update multiple values on diferent rows or in the same row with the dinamic query db_update .
注意:通过批量更新,只能将一个查询发送到服务器,而不是每行要更新一个查询。
句法:
UPDATE yourTableName
SET yourUpdateColumnName =
(CASE yourConditionColumnName WHEN Value1 THEN 'UpdatedValue'
WHEN Value2 THEN 'UpdatedValue'
.
.
N
END)
WHERE yourConditionColumnName IN(Value1,Value2,.....N);
有关UpdateQuery上的表达式的更多信息:https://api.drupal.org/api/drupal/includes%21database%21query.inc/function/UpdateQuery%3A%3Aexpression/7.x
您的数据将是:
//Create array
$for_update = [
1 => "85590762,22412382,97998072",
3 => "22412382",
];
$item_ids_to_filter = [];
//Setup when-then conditions
$when_then = "CASE item_id ";
foreach ($for_update as $item_id => $users_id) {
$when_then .= "WHEN {$item_id} THEN '{$users_id}' ";
$item_ids_to_filter[] = $item_id;
}
$when_then .= "END";
//Execute query and update the data with db_update
db_update('items')
->expression("users",$when_then)
->condition('item_id', $item_ids_to_filter)
->execute();
结果生成下一个查询:
UPDATE items
SET users =
(CASE item_id = WHEN 1 THEN '85590762,22412382,97998072'
WHEN 3 THEN '22412382'
END)
WHERE (item_id IN ('1', '3'))
我想你可以做点什么
$query = db_udpate('table')->fields(array('field_1','field_2','field_3'));
foreach ($fields as $record) {
$query->values($record);
}
return $query->execute();
$ fields = array('field_1'=> VALUE,'field_2'=> VALUE)
以上是关于Drupal 7 |使用db_update更新多行的主要内容,如果未能解决你的问题,请参考以下文章