Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ssquare's avatar

Return ID From updateOrInsert Laravel query builder

How to return the id of las updated or Inserted id.

I am using query builder instead of eloquent. How can I return ID from the following example:

DB::table('users')
    ->updateOrInsert(
        ['email' => '[email protected]', 'name' => 'John'],
        ['votes' => '2']
    );
0 likes
9 replies
Digitalized's avatar

Unlike updateOrCreate which returns the updated model, updateOrInsert just returns a boolean response. If you want to get the last inserted ID, you can do the following just after your query:

$last_id = Illuminate\Support\Facades\DB::getPdo()->lastInsertId();
varun-2301's avatar

You can use updateOrCreate in place of updateOrInsert to get the required result.

$user = DB::table('users')
    ->updateOrCreate(
        ['email' => '[email protected]', 'name' => 'John'],
        ['votes' => '2']
    );
1 like
ssquare's avatar

@varun-2301 I don't think there is a method like updateOrCreate for query builder, that is available only in the eloquent model.

Cronix's avatar

The only accurate way to get the id of the inserted or updated record is to requery it using the same conditions that you are using for the where portion of the query (first array).

DB::table('users')
    ->updateOrInsert(
        ['email' => '[email protected]', 'name' => 'John'],
        ['votes' => '2']
    );
$updatedOrInsertedRecord = DB::table('users')
    ->where('email', '[email protected]')
    ->where('name', 'John')
    ->first();

echo $updatedOrInsertedRecord->id;
2 likes
Digitalized's avatar

@cronix reply seems to be the most sensible to me if you want to use the updateOrInsert method

Of course you could always use the updateOrCreate method instead, which returns the updated/created model. If you are using an auto-increment ID in your database table and you are not specifying the ID in the data array, then I don't think there's any reason to use updateOrInsert

ssquare's avatar

@cronix Although I am using as follows, it is taking way lot of time to insert data. It goes increasing as the size of the table increased.

DB::beginTransaction();
$r = Model::where($conditions)->first();
if($row){
                try{
                         $row = DB::table('table1')
                                                        ->where('id', $r->id)
                                                        ->update($data_arr);
                                            $row_id= $row ->id;
                                        } catch (\Exception $e) {
                                            $this->error_arr[] = $e->getMessage();
                                            $this->error_row_numbers[] = $this->data['row_value']; 
                                            DB::rollback(); 
                           }
}else{
 try{
                         $row_id = DB::table('table_1')->insertGetId(
                                                $data_arr
                                            );
                                        } catch (\Exception $e) {
                                            $this->error_arr[] = $e->getMessage();
                                            $this->error_row_numbers[] = $this->data['row_value']; 
                                            DB::rollback(); 
                           }
}

Now, using this $row_id I will find the row on table 2. If exists update else create just as in above code. This is taking too much time. To insert around 200,000 it is taking around 2 days. Now, what is the best way to deal with this? This is currently residing inside the job.

Cronix's avatar

Of course it will be slower. It's performing an extra query for everything. If there were 2000 queries before, now there's 4000. I didn't say it's the best way, only the way that will do what you want - get the id whether it's an insert OR update.

If your email and name fields are indexed, it shouldn't really take that long though. Those need to be indexed because that's what you're using in your where portion of the query. It takes longer as more data gets inserted because there aren't any indexes for it to use, so it has to scan the entire table every time to find that record to see if it exists. I'm betting they're not indexed.

1 like
ssquare's avatar

@cronix Actually, I already have an index of (id, name, city, state, zip). The code in question is just pasted from laravel documentation itself. I need to check if there is already a row with the same name, city, state, zip.

Please or to participate in this conversation.