12 votes

Laravel Bulk Update pour plusieurs identifiants d'enregistrement

Je veux mettre à jour en masse mes enregistrements dans Laravel mais les enregistrements ne sont pas mis à jour. J'ai un enregistrement différent pour chaque Id. Voici ce que j'essaie de faire.

$ids = [5,6,8,9],
$updated_array = [
  ['name' => 'tarun'],
  ['name' => 'Akash'],
  ['name' => 'Soniya'],
  ['name' => 'Shalu'],
];

Model::whereIn('id', $ids)->update($updated_array);

0 votes

Dans votre modèle, définissez protected $guarded = array(); $fillable y $guarded sont utilisées pour permettre l'insertion et la mise à jour en masse

18voto

Devon Points 1551

Les mises à jour en masse sont utilisées lorsque vous essayez de mettre à jour plusieurs lignes avec les mêmes valeurs. Vous ne pouvez pas effectuer de mises à jour en masse avec des valeurs différentes.

Cela fonctionnerait donc, mais mettrait à jour tous les enregistrements correspondants au nom de "tarun" :

Model::whereIn('id', $ids)->update(['name' => 'tarun']);

Pour votre exemple, vous pourriez faire :

foreach($ids as $key => $id) {
    Model::where('id', $id)->update($updated_array[$key]);
}

Mais pour autant que je sache, il n'y a aucun moyen de faire cela sans exécuter 4 requêtes dans Laravel et écrire une déclaration SQL brute pour accomplir cela serait même désordonné.

5voto

Dadan Satria Points 61

Vous pouvez utiliser Laravel Upsert pour une mise à jour en masse. Par exemple :

User::query()->upsert([
    ['id' => 1, 'email' => 'dadan@example.com'],
    ['id' => 2, 'email' => 'satria@example.com'],
], 'email');

Cette fonctionnalité est disponible dans Laravel 8 ou plus récent.

4voto

Sami El Maameri Points 57

Vous trouverez de bonnes solutions à ce problème dans le billet suivant : https://github.com/laravel/ideas/issues/575

1) Il est possible de créer une fonction personnalisée pour ce faire, qui utilise le SQL brut, comme l'indique le commentaire de barryvdh dans l'article.

    public static function updateValues(array $values)
    {
        $table = MyModel::getModel()->getTable();

        $cases = [];
        $ids = [];
        $params = [];

        foreach ($values as $id => $value) {
            $id = (int) $id;
            $cases[] = "WHEN {$id} then ?";
            $params[] = $value;
            $ids[] = $id;
        }

        $ids = implode(',', $ids);
        $cases = implode(' ', $cases);
        $params[] = Carbon::now();

        return \DB::update("UPDATE `{$table}` SET `value` = CASE `id` {$cases} END, `updated_at` = ? WHERE `id` in ({$ids})", $params);
    }

Il semblerait que les performances soient multipliées par 13

2) Comme indiqué dans un autre commentaire, une autre idée consiste à procéder par enregistrement, mais en effectuant l'ensemble en une seule transaction, ce qui est beaucoup plus rapide.

    DB::beginTransaction();

    // your loop and updates;

    if( !$user )
    {
    rollbackTransaction();
    } else {
    // Else commit the queries
    commitTransaction();
    }

3) Il existe également une bibliothèque Laravel qui semble essayer de résoudre ce problème. https://github.com/mavinoo/laravelBatch

Note : Je n'ai essayé ni testé aucune des solutions ci-dessus.

2voto

Je pense que la seule façon de procéder sans n requêtes serait de

  • (facultatif) table de sauvegarde
  • récupérer les enregistrements et créer un tableau avec toutes les données mises à jour
  • supprimer en bloc les enregistrements
  • insertion en bloc dans un tableau

Cela fait 3 requêtes.

L'itération sur n enregistrements n'est pas non plus pratique pour mon application ; j'espérais qu'il y aurait une alternative mais il semble que je vais devoir implémenter ceci.

0voto

Arab Points 1

Veuillez essayer le code ci-dessous pour la mise à jour de masse

 <ModelName>::where('id', $id)->update($request->all());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X