Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bulk insert and get returned ids laravel

Tags:

I have an array like this one :

 0 => array:2 [
    "name" => "Data1"
    "type" => "value1"
  ],
 1 => array:2 [
    "name" => "Data2"
    "type" => "value2"
  ]

i want to insert them in single query in the database and retrieve their ids without any additional query.

So far i have tried insertGetId

MyModel::insertGetId($array)

but i have noticed it inserts bulk rows but return the last id.

like image 455
wahdan Avatar asked Sep 04 '17 15:09

wahdan


2 Answers

Well You Can Get The Last Id from the table .. Then After The Insertion Add The Last id To The Count of your array .. But you Will face a problem and that is if you have 2 or more users inserted some records into this table at the same time .. so you can use The Transaction

 try{
    DB::beginTransaction();

   // 1- get the last id of your table ($lastIdBeforeInsertion)

   // 2- insert your data
    Model::insert($array);

  // 3- Getting the last inserted ids
  $insertedIds = [];
  for($i=1; $i<=theCountOfTheArray; $i++)
     array_push($insertedIds, $lastIdBeforeInsertion+$i);

});

    DB::commit();
}catch(\Exception $e){
    DB::rollback();
}

or

DB::transaction(function() {

   // 1- get the last id of your table ($lastIdBeforeInsertion)

   // 2- insert your data
   Model::insert($array);

  // 3- Getting the last inserted ids
  $insertedIds = [];
  for($i=1; $i<=theCountOfTheArray; $i++)
     array_push($insertedIds, $lastIdBeforeInsertion+$i);

});

Database Transaction Documentation

Very Useful Article About Database Transactions

Edit

You Can make a unique Column and Call it for Example unique_bulk_id .. This will hold randomly generated string for the inserted data .. after the insertion you can get the inserted data by This unique_bulk_id.

like image 99
Ali Beshir Avatar answered Oct 14 '22 03:10

Ali Beshir


As I commented in @ali-beshir's answer;

$lastIdBeforeInsertion may not be a source of truth. When the last record is deleted it create a gap. Example : Your last record has the ID 23, you delete it, your last id will be 22 but your next record will have the ID 24.

So I did by getting the last ID only which is, I think, more reliable.

DB::transaction(function() {

    Model::insert($data);
   
    $lastId = Model::orderByDesc('id')->first()->id;

    $ids = range($lastId - count($data) + 1, $lastId);

});
like image 38
Clément Baconnier Avatar answered Oct 14 '22 01:10

Clément Baconnier