Массовое обновление в Laravel с определенным условием где для каждой строки

Я занимаюсь разработкой веб-сайта на основе базы данных с использованием Laravel. Теперь у меня проблема с обновлением базы данных. Я хочу запустить массовое обновление. Обычно я бегаю так.

 $data = [
[
'col_1'=>$value1
],
[
'col_1'=>$value2
],
[
'col_1'=>$value3
],
[
'col_1'=>$value4
]
];
MyTableObject::update($data)->where('col_2'=>$col_2_val);

Как вы можете видеть в приведенном выше коде, где условие проверяет только одно условие для всех строк, которые должны быть обновлены. Но то, что я хочу, это то, что я хочу различное условие условия where для каждой строки или запроса. Чтобы использовать foreach и выполнять запрос для каждой строки, это займет много времени, потому что мне нужно обновить много строк. Чтобы продемонстрировать это, это будет что-то вроде этого.

$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');

я нашел эта ссылка, но ответы не ясны и полны. Можно ли сделать это в Laravel и как я могу это сделать?

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']]);
});
0

Другие решения

Вот функция пакетного обновления, которую я написал для использования в моих проектах Laravel. Его первый параметр — это строка имени таблицы, второй — это строка имени ключа, для которой вы хотите обновить строку или строки, и в основном это будет ‘id’, третий параметр — это массив данных в формате:

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;
}

Он выдаст и выполнит строку запроса следующим образом:

UPDATE table_name SET col_1_name = CASE
WHEN id = '1' THEN 'col_1_value'
WHEN id = '2' THEN 'col_1_value'
ELSE col_1_name END,
col_2_name = CASE
WHEN id = '1' THEN 'col_2_value'
WHEN id = '2' THEN 'col_2_value'
ELSE col_2_name END
WHERE id IN('1','2')
0