Làm cách nào để cập nhật nhiều hàng với các giá trị khác nhau trong laravel?

Ví dụ: giả sử chúng tôi đã thiết kế một phần mềm kiểm kê và phần mềm này đang được sử dụng trong sản xuất trong một năm và đạt 1.000.000 giao dịch

Đột nhiên, chúng tôi biết rằng chúng tôi đã không thêm VAT vào các giao dịch của mình. Đối với các giao dịch trong tương lai, nó khá dễ xử lý, có thể với một công cụ biến đổi

class Transaction extends Model { 
    public $vat = 0.20;

    public function setPriceAttribute[$value] {
        $this->attributes['price'] += $value * $this->vat;
    }
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hồ sơ trong tương lai là khá dễ dàng để đối phó với. Tuy nhiên, làm thế nào chúng ta sẽ chỉnh sửa 1 triệu bản ghi từ quá khứ

Để chỉnh sửa dữ liệu từ quá khứ, tôi thích tạo Seeder hơn

php artisan make:seeder AddVatToTransactions

Làm thế nào để không làm điều đó?


class AddVatToTransactions extends Seeder {

  public function run[] 
  {
    $vat = 0.20;
    $transactions = Transaction::get[];

    foreach [$transactions as $transaction] {
       $transaction->price += $transaction->price * $vat
       $transaction->save[];
    }
  }
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Tuy nhiên, chạy nó trong một vòng lặp 1 triệu và thực hiện một “giao dịch cơ sở dữ liệu” trong mỗi lần lặp của vòng lặp - không phải là một ý tưởng hay. [Cảnh báo spoiler. Nó sẽ đóng băng hệ thống của bạn 😀]

Sớm muộn gì bạn cũng sẽ rơi vào tình huống cần cập nhật nhiều bản ghi cơ sở dữ liệu với các giá trị khác nhau. Laravel hỗ trợ cập nhật hàng loạt khi chỉ có một khả năng giá trị cho cột đã cho. Trong tài liệu chúng ta có thể tìm thấy ví dụ này

Flight::where['active', 1]
->where['destination', 'San Diego']
->update[['delayed' => 1]];

Điều này sẽ đặt thuộc tính bị trì hoãn thành đúng cho tất cả các chuyến bay đang hoạt động và có điểm đến là San Diego. Trong trường hợp này, điều này hoàn toàn ổn, nó sẽ chỉ sử dụng một truy vấn và nó sẽ khá nhanh. Nhưng nếu chúng ta muốn cập nhật nhiều bản ghi với các giá trị khác nhau thì sao? . Một số người dùng có 10 điểm, một số 20, v.v. Sẽ có một truy vấn cho mọi người dùng mà chúng tôi muốn cập nhật
Nếu chúng tôi phải cập nhật 5000 bản ghi, chúng tôi sẽ cần sử dụng vòng lặp

// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
0 và thực hiện 5000 truy vấn. Tôi đã cố gắng mô phỏng tình huống này và so sánh xem sẽ mất bao nhiêu thời gian để hoàn thành công việc. Vì vậy, tôi đã tạo cơ sở dữ liệu với 100 000 người dùng, chuẩn bị dữ liệu để cập nhật và chạy nó bên trong vòng lặp
// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
0

// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}

Trung bình mất 5. 47676 giây để cập nhật dữ liệu

Chúng tôi có thể bao bọc giao dịch nội bộ này và nó sẽ có tác động lớn đến hiệu suất

DB::transaction[function[] use[$ids, $data] {
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
}];

Chúng ta đang nói về 1. Trung bình 68872 giây. Điều này tốt hơn nhiều nhưng chúng ta có thể cải thiện điều này hơn nữa không?

Hãy thử thực hiện công việc tương tự bằng cách sử dụng gói cập nhật hàng loạt cho Laravel

use Mavinoo\Batch\Batch;
use App\Models\User;
/* $updateData is array with length of 5000 and structure like this:
$updateData = [
[’id' => 100, 'points' => 200],
[’id' => 500, 'points' => 300] ...
]
*/
Batch::update[new User, $updateData, 'id'];

Tham số đầu tiên là mô hình chúng tôi muốn cập nhật, tham số thứ hai là dữ liệu và tham số thứ ba là cột xác định duy nhất các bản ghi trong bảng được liên kết
Điều này chỉ mất 1. 0531 giây trung bình và một truy vấn duy nhất. Điều này đã được thực hiện bằng chức năng CASE của MySql
Bây giờ, hãy kiểm tra gói này và xem phương thức cập nhật hoạt động như thế nào bằng cách tập trung vào các phần quan trọng nhất của mã

________số 8_______

Hãy tưởng tượng rằng phần tử đầu tiên của

// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
2 là mảng này

// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
3
Chúng tôi có hai vòng lặp foreach lồng nhau. Cái đầu tiên sẽ lặp lại trên
// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
2 của chúng ta, mảng gồm 5000 mảng. Nó sẽ trích xuất giá trị của 'id' từ mảng đầu tiên và đẩy nó vào bên trong
// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
5array
// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
6 sẽ bằng 100

$finalField = $raw ? Common::mysql_escape[$val[$field]]:  "'" . Common::mysql_escape[$val[$field]] . "'";
$value = [is_null[$val[$field]] ? 'NULL' :
$final[$field][] = 'WHEN `' . $index . '` = \'' . $val[$index] . '\' THEN ' . $value . ' ';

Vòng lặp tiếp theo sẽ trích xuất các trường cần được cập nhật. Trong trường hợp của chúng tôi, giá trị của trường $ sẽ là chuỗi 'điểm' và giá trị của

// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
7 sẽ là '230'. Chúng tôi an toàn trước SQL injection vì các biến này được truyền qua hàm
// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
8
Bước cuối cùng là tạo mảng có tên của cột cần được cập nhật làm khóa và chuỗi đại diện cho câu lệnh đã chuẩn bị cho hàm CASE của MySql làm giá trị. Sau đó, chúng tôi đẩy mảng đó vào bên trong biến
// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
9
Vì vậy, sau khi thực hiện vòng lặp
// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
0 thứ hai, mảng
// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
9 sẽ trông như thế này

array:1 [
"points" => array:1 [
0 => "WHEN `id` = '100' THEN '230' "
]
]

Chúng tôi chỉ cập nhật cột 'điểm' nhưng nếu chúng tôi cũng cập nhật một số cột khác, nó cũng sẽ thêm chúng

array:1 [
"points" => array:1 [
0 => "WHEN `id` = '100' THEN '230' "
],
"something" => array:1 [
0 => "WHEN `id` = '100' THEN 'some_value' "
]
]

Khi cả hai vòng lặp được thực hiện, mảng

DB::transaction[function[] use[$ids, $data] {
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
}];
2 sẽ bao gồm 5000 chuỗi giống như chuỗi ở trên

Cuối cùng, nó sẽ tạo một chuỗi truy vấn bằng cách kết hợp các giá trị từ các mảng

// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
9và
// $ids = array of random user ids
// $data = array of random numbers for points
for [$i = 0; $i $ids[$i]]]
->update[['points' => $data[$i]]];
}
5

Làm cách nào để cập nhật nhiều hàng cùng một lúc trong laravel?

Có 3 cách đơn giản để cập nhật nhiều bản ghi hoặc cột trong ứng dụng laravel. .
Phương pháp 1 – Cập nhật nhiều bản ghi với Where[]
Phương pháp 2 – Cập nhật nhiều bản ghi với WhereIn bằng Id
Phương pháp 3 – Cập nhật nhiều bản ghi với WhereIn[] sử dụng Dữ liệu yêu cầu

Làm cách nào để cập nhật nhiều hàng trong SQL với các giá trị khác nhau?

Có một số cách để thực hiện. CHÈN VÀO học viên [id, điểm1, điểm2] GIÁ TRỊ [1, 5, 8], [2, 10, 8], [3, 8, 3], [4, 10, 7

Làm cách nào để cập nhật nhiều hàng trong Laravel 8?

Hãy thử như thế này. ĐB. table['data'] ->where['category_id', '=', 1] ->update[[ 'subject' => $request->get['subject'] ?? null, 'grade' => $ . success['cập nhật thành công'];

Làm cách nào để cập nhật tất cả các hàng trong laravel?

Giải pháp cập nhật tất cả các hàng. .
Tạo một cột bổ sung [như 'updateAll'] và gán giá trị tĩnh cho tất cả các hàng [như thế này 'updateAll' = '1'] trong bảng mysql
Thêm trường nhập ẩn với name="forUpdateAll" và value="forUpdateAllValue" [để chỉ thực thi mã cụ thể để cập nhật tất cả các hàng]

Chủ Đề