You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel使用upsert通过数组更新数据却重复插入的问题求助

问题分析与修复方案

核心错误点

  1. Upsert参数格式错误
    Laravel的upsert方法第一个参数要求是多维数组(批量数据结构),你当前传入的是单条数据的一维数组,这会导致方法无法正确识别重复判断逻辑,进而触发重复插入。

  2. 软删除数据的识别问题
    withTrashed()不会让upsert识别软删除记录——数据库层面,软删除记录的deleted_at字段不为null,即使companion_animal_form_id相同,数据库会判定为两条不同记录,因此依然会插入新数据。

  3. 缺少数据库唯一约束
    upsert依赖数据库的唯一索引/约束判断重复。如果companion_animal_form_id未设置唯一约束,数据库无法识别重复记录,只会执行插入操作。

修复步骤

步骤1:修正Upsert参数格式

将单条数据包装为多维数组传入:

// 把单条数据嵌套进数组
$vaccines = [
    [
        'companion_animal_form_id' => $formId,
        'vaccine' => $vaccine['vaccine'],
        'vaccine_date' => $vaccine['vaccine_date'],
        'veterinarian_code' => $vaccine['veterinarian_code'],
        'record_user' => $timeStampLog,
    ]
];

CompanionAnimalRabiesVaccination::upsert(
    $vaccines,
    ['companion_animal_form_id'],
    ['vaccine', 'vaccine_date', 'veterinarian_code', 'record_user','deleted_at']
);

步骤2:处理软删除记录(可选)

若要更新软删除的记录,需先恢复再执行upsert,或直接用updateOrCreate处理单条数据:

// 恢复对应ID的软删除记录(如果存在)
CompanionAnimalRabiesVaccination::withTrashed()
    ->where('companion_animal_form_id', $formId)
    ->restore();

// 执行upsert
CompanionAnimalRabiesVaccination::upsert(
    $vaccines,
    ['companion_animal_form_id'],
    ['vaccine', 'vaccine_date', 'veterinarian_code', 'record_user']
);

// 或直接用updateOrCreate更简洁处理单条数据
CompanionAnimalRabiesVaccination::updateOrCreate(
    ['companion_animal_form_id' => $formId],
    [
        'vaccine' => $vaccine['vaccine'],
        'vaccine_date' => $vaccine['vaccine_date'],
        'veterinarian_code' => $vaccine['veterinarian_code'],
        'record_user' => $timeStampLog,
        'deleted_at' => null // 恢复软删除需设置为null
    ]
);

步骤3:添加数据库唯一约束

在迁移文件中给companion_animal_form_id添加唯一索引:

Schema::table('companion_animal_rabies_vaccinations', function (Blueprint $table) {
    $table->unique('companion_animal_form_id');
});

执行迁移命令:

php artisan migrate

注意事项

  • 若业务允许同一个companion_animal_form_id存在正常记录和软删除记录,可设置companion_animal_form_id与deleted_at的组合唯一索引,但该场景极少。
  • upsert底层依赖数据库的INSERT ... ON DUPLICATE KEY UPDATE(MySQL)等语法,唯一约束是功能生效的前提。

内容的提问来源于stack exchange,提问作者Email Puna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 03:35:17