雄辩的质量插入,ON DUPLICATE KEY UPDATE

时间:2014-09-24 20:41:57

标签: php mysql orm eloquent

我在做:

$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。有什么想法怎么做?或者在列表中忽略重复项?

提前致谢...

2 个答案:

答案 0 :(得分:2)

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

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`))" 

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

答案 1 :(得分:1)

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,至少有一个插入的值必须包含主键或唯一键。