我正在使用Laravel开发一个数据库驱动的网站。现在我遇到更新数据库的问题。我想运行批量更新。通常我会这样跑。
$data = [
[
'col_1'=>$value1
],
[
'col_1'=>$value2
],
[
'col_1'=>$value3
],
[
'col_1'=>$value4
]
];
MyTableObject::update($data)->where('col_2'=>$col_2_val);
正如您在上面的代码中所看到的,where子句只检查要更新的所有行的一个条件。但我想要的是我想要每个行或查询的不同where子句条件。要为每一行使用foreach和run查询,这将非常耗时,因为我必须更新很多行。为了证明它,它将是这样的。
$data = [
[
'col_1'=>$value1,
'col_2'=>$where_value_1 // This is not the column to be updated. That is for where clause.
],
[
'col_1'=>$value2,
'col_2'=>$where_value_2 // This is not the column to be updated. That is for where clause.
],
[
'col_1'=>$value3,
'col_2'=>$where_value_3
],
[
'col_1'=>$value4,
'col_2'=>$where_value_4
]
];
MyTableObject::update($data)->where('where_col_name'=>'col_2');
我找到了this link,但答案并不明确和完整。是否可以在Laravel中完成,我该怎么办?
答案 0 :(得分:0)
这是我在Laravel项目中使用的批量更新功能。它的第一个参数是表名字符串,第二个是要更新一行或多行的键名字符串,大部分是'id',第三个参数是格式的数据数组:
$_GET
功能:
array(
array(
'id' => 1,
'col_1_name' => 'col_1_val',
'col_2_name' => 'col_2_val',
//.....
),
array(
'id' => 2,
'col_1_name' => 'col_1_val',
'col_2_name' => 'col_2_val',
//.....
),
//.....
);
它将生成并执行如下的查询字符串:
private function custom_batch_update(string $table_name = '', string $key = '', Array $update_arr = array()) {
if(!$table_name || !$key || !$update_arr){
return false;
}
$update_keys = array_keys($update_arr[0]);
$update_keys_count = count($update_keys);
for ($i = 0; $i < $update_keys_count; $i++) {
$key_name = $update_keys[$i];
if($key === $key_name){
continue;
}
$when_{$key_name} = $key_name . ' = CASE';
}
$length = count($update_arr);
$index = 0;
$query_str = 'UPDATE ' . $table_name . ' SET ';
$when_str = '';
$where_str = ' WHERE ' . $key . ' IN(';
while ($index < $length) {
$when_str = " WHEN $key = '{$update_arr[$index][$key]}' THEN";
$where_str .= "'{$update_arr[$index][$key]}',";
for ($i = 0; $i < $update_keys_count; $i++) {
$key_name = $update_keys[$i];
if($key === $key_name){
continue;
}
$when_{$key_name} .= $when_str . " '{$update_arr[$index][$key_name]}'";
}
$index++;
}
for ($i = 0; $i < $update_keys_count; $i++) {
$key_name = $update_keys[$i];
if($key === $key_name){
continue;
}
$when_{$key_name} .= ' ELSE ' . $key_name . ' END, ';
$query_str .= $when_{$key_name};
}
$query_str = rtrim($query_str, ', ');
$where_str = rtrim($where_str, ',') . ')';
$query_str .= $where_str;
$affected = DB::update($query_str);
return $affected;
}
答案 1 :(得分:0)
如果我正确理解了这一点,col_1是您希望在更新中使用的值,col_2是您要查询的值。尝试以下(可能需要一些调整)
collect($data)->each(function(array $row) {
MyTableObject::where('where_col_name', $row['col_2'])->update(['col_1' => $row['col_1']]);
});