0

我正在使用 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 并运行查询,这将非常耗时,因为我必须更新很多行。为了证明这一点,它将是这样的。

$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 中做到这一点,我该怎么做?

4

2 回答 2

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']]);
});
于 2018-02-02T12:14:40.237 回答
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')
于 2018-02-02T12:00:27.363 回答