大量插入,重复密钥更新


Eloquent mass insert, ON DUPLICATE KEY UPDATE

我在做:

$data = [
        ['amodule'=>'amodule', 'akey'=>'first_example', 'avalue'=>'4096', 'created_at'=>'2014-09-21'],
        ['amodule'=>'amodule2', 'akey'=>'sec_example', 'avalue'=>'4097', 'created_at'=>'2014-09-22'],
        ['amodule'=>'amodule2', 'akey'=>'sec_example', 'avalue'=>'4097', 'created_at'=>'2014-09-22'],
    ];
    Models'Snapshot::insert($data);

只是执行大规模插入。现在我想给它添加一个ON DUPLICATE KEY。你知道怎么做吗?或者在列表中忽略重复项?

提前感谢。。。

Eloquent目前不支持这一点,您必须将其写成原始查询。

// generates (?,?,?,?),(?,?,?,?),(?,?,?,?),(?,?,?,?)
$valueString = implode(',', array_fill(0, count($data), '(' . implode(',', array_fill(0, count($data[0]), '?')) . ')')); 
$values = [];
// Flattens the array
foreach($data as $row) {
    foreach($row as $value) {
        $values[] = $value;
    }
}
// Perform the insert
'DB::insert(
    "insert into `snapshots` (`amodule`, `akey`, `avalue`, `created_at`) values {$values} on duplicate key update",
    $values
);

请记住,为了触发on duplicate key update,插入的值中至少有一个必须具有主键或唯一键。

如果您想在单个查询中执行大规模插入,那么您应该使用upstart方法。该方法的第一个参数由要插入或更新的值组成,而第二个参数列出了唯一标识关联表中记录的列。该方法的第三个也是最后一个参数是列的数组,若数据库中已经存在匹配的记录,则应更新该数组。

Snapshot::upsert([
        ['amodule'=>'amodule', 'akey'=>'first_example', 'avalue'=>'4096', 'created_at'=>'2014-09-21'],
        ['amodule'=>'amodule2', 'akey'=>'sec_example', 'avalue'=>'4097', 'created_at'=>'2014-09-22'],
        ['amodule'=>'amodule2', 'akey'=>'sec_example', 'avalue'=>'4097', 'created_at'=>'2014-09-22'],
    ], ['amodule', 'akey'], ['avalue']);

如果只给出两个参数,那么第二个参数是在发现重复时需要更新的列。

Snapshot::upsert([
        ['amodule'=>'amodule', 'akey'=>'first_example', 'avalue'=>'4096', 'created_at'=>'2014-09-21'],
        ['amodule'=>'amodule2', 'akey'=>'sec_example', 'avalue'=>'4097', 'created_at'=>'2014-09-22'],
        ['amodule'=>'amodule2', 'akey'=>'sec_example', 'avalue'=>'4097', 'created_at'=>'2014-09-22'],
    ], ['avalue']);

然而,laravel建议给出所有三个论点,以避免任何可能的雄辩的大规模分配错误。上述方法将创建此查询

    insert into `snapshots` (`amodule`, `akey`, `avalue`) values (amodule, amodule, 4096) on duplicate key update 
`amodule` = values(`amodule`), `akey` = values(`akey`),
 `avalue` = values(`avalue`))" 

如果在模型上启用了时间戳,则upstart方法将自动设置created_at和updated_at时间戳: