34
loading...
This website collects cookies to deliver better user experience
UPSERT
is your solutionUPSERT
is one of the essential features of DBMS software for managing the database. This operation allows the DML users to insert a new record or update existing data into a table. An UPSERT
is made up of a combination of two words named UPDATE
and INSERT
. The first two letters, i.e., UP stands for UPDATE while the SERT stands for INSERT.INSERT ON DUPLICATE KEY UPDATE
statement is a non-destructive method that means it does not remove the duplicate row. Instead, when we specify the ON DUPLICATE KEY UPDATE clause in a SQL statement and a row would cause duplicate error value in a UNIQUE
or PRIMARY KEY
index column, then updating the existing row occurs.INSERT INTO table (column_names)
VALUES (data)
ON DUPLICATE KEY UPDATE
column1 = expression, column2 = expression…;
Dean Ngo
, and email is [email protected], his age and address columns will be updated. If no such user exists, a new user will be created. Especially, you wish to perform multiple records in one query$data = [
['fullname' => 'Dean Ngo', 'email' => '[email protected]', 'age' => 20, 'address' => 'Danang'],
['fullname' => 'Bean Roman', 'email' => '[email protected]', 'age' => 25, 'address' => 'Countryard'],
];
// App\Traits\QueryKit.php
<?php
namespace App\Traits;
use Illuminate\Support\Facades\DB;
trait QueryKit
{
/**
* Insert new rows or update existed rows
*
* @param array $data
* @param array $insertKeys
* @param array $updateKeys
*
* @return void
*/
public static function insertDuplicate(array $data, array $insertKeys, array $updateKeys)
{
$model = new static;
$query = "INSERT INTO {$model->getTable()} __INSERTKEYS__ VALUES __INSERTVALUE__ ON DUPLICATE KEY UPDATE __UPDATEVALUES__";
$tmpInKeys = array_fill_keys($insertKeys, null);
$tmpUpKeys = array_fill_keys($updateKeys, null);
try {
DB::beginTransaction();
foreach ($data as $item) {
$insertValue = array_intersect_key($item, $tmpInKeys);
$updateValue = implode(', ', array_map(
function ($v, $k) { return sprintf("`%s`='%s'", $k, $v); },
array_intersect_key($item, $tmpUpKeys),
$updateKeys
));
$statement = str_replace(
['__INSERTKEYS__', '__INSERTVALUE__', '__UPDATEVALUES__'],
["(`" . implode("`,`", $insertKeys) . "`)", "('" . implode("','", $insertValue) . "')", $updateValue],
$query
);
DB::statement($statement);
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
report($e);
throw new \Exception($e->getMessage());
}
}
}
insertDuplicate(array $data, array $insertKeys, array $updateKeys)
First argument consists of the values to insert or update
Second argument lists the column(s) that uniquely identify records within the associated table
Third argument is an array of the columns that should be updated if a matching record already exists in the database.
// App\Models\User.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Guardian\Traits\QueryKit;
class User extends Model
{
use SoftDeletes;
use QueryKit;
protected $table = "users";
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['fullname', 'email', 'age', 'address'];
}
$data = [
['fullname' => 'Dean Ngo', 'email' => '[email protected]', 'age' => 20, 'address' => 'Danang'],
['fullname' => 'Bean Roman', 'email' => '[email protected]', 'age' => 25, 'address' => 'Countryard'],
];
\App\Models\User::insertDuplicate(
$data,
['fullname', 'email'],
['age', 'address']
);