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

Laravel 9中updateOrInsert仅插入不更新问题求助

Laravel 9 updateOrInsert 始终执行插入不更新的问题排查与解决

问题场景

在Laravel 9项目中使用updateOrInsert方法实现数据去重,期望存在匹配记录时执行更新,不存在时执行插入,但实际始终触发插入操作,更新功能失效。以下是原代码实现:

<?php

namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Models\Wip;
use App\Models\db2;

class WipController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $tgl_skrg = date('Y-m-d 00:00:00');
        $tgl_skrg2 = date('Y-m-d 23:00:00');
        $nilai = '00017';
       
        $db2s = DB::connection('mysql2')->table("wip_tracking_1")->get();
        
        $data = json_decode($db2s, true);

        foreach ($data as $db2 ){
           DB::table('wip_tracking')
            ->updateOrInsert(
                [
                "TP" =>$db2 ['TP'],
                "TP_code"=>$db2 ['TP_code'],
                "VIN"=>$db2 ['VIN'] ,
                "Flag"=>$db2 ['Flag'] ,
                "Suffix"=>$db2 ['Suffix'] ,
                "Color_Code"=>$db2 ['Color_Code'] ,
                "Scan_date"=>$db2 ['Scan_date'] ,
                "Production_date"=>$db2 ['Production_date'] ,
                "Production_shift"=>$db2 ['Production_shift'] ,
                "Model_code"=>$db2 ['Model_code'] ,
                "Brand"=>$db2 ['Brand'] ,
                "Destination_code"=>$db2 ['Destination_code'] ,
                "WIP_code"=>$db2 ['WIP_code'] ,
                "ADM_Production_ID"=>$db2 ['ADM_Production_ID'] ,
                "Plan_delivery_date"=>$db2 ['Plan_delivery_date'] ,
                "created_at" => date('Y-m-d H:i:s'),
                ],
                [
                    "ADM_Production_ID"=> $db2['ADM_Production_ID']
                ],
                [
                    "VIN"=> $db2['VIN']
                ],

            );
            
          
        } 
                    
 
    }

错误原因

updateOrInsert方法仅接受两个参数:

  1. 第一个参数:用于判断记录是否存在的查询条件数组(通常是唯一标识字段)
  2. 第二个参数:记录存在时要更新的字段,或不存在时要插入的字段数组

原代码存在两个核心错误:

  • 传入三个参数,超出方法定义,第三个参数会被直接忽略
  • 第一个参数包含了created_at(每次执行都会生成新时间)以及大量非唯一字段,导致每次查询都无法匹配到已有记录,因此始终触发插入操作

解决方案

修正updateOrInsert的参数结构,以业务唯一标识字段(如VIN,车辆识别码通常全局唯一)作为查询条件,将所有需要同步的字段放在第二个参数中。同时遵循Laravel规范,新增updated_at记录更新时间,created_at仅在插入时设置。

修正后的代码示例:

<?php

namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Models\Wip;
use App\Models\db2;

class WipController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $tgl_skrg = date('Y-m-d 00:00:00');
        $tgl_skrg2 = date('Y-m-d 23:00:00');
        $nilai = '00017';
       
        $db2s = DB::connection('mysql2')->table("wip_tracking_1")->get();
        
        $data = json_decode($db2s, true);

        foreach ($data as $db2 ){
           DB::table('wip_tracking')
            ->updateOrInsert(
                // 第一个参数:查询条件,用唯一标识VIN判断记录是否存在
                ["VIN" => $db2['VIN']],
                // 第二个参数:要插入或更新的所有字段
                [
                    "TP" => $db2['TP'],
                    "TP_code" => $db2['TP_code'],
                    "Flag" => $db2['Flag'],
                    "Suffix" => $db2['Suffix'],
                    "Color_Code" => $db2['Color_Code'],
                    "Scan_date" => $db2['Scan_date'],
                    "Production_date" => $db2['Production_date'],
                    "Production_shift" => $db2['Production_shift'],
                    "Model_code" => $db2['Model_code'],
                    "Brand" => $db2['Brand'],
                    "Destination_code" => $db2['Destination_code'],
                    "WIP_code" => $db2['WIP_code'],
                    "ADM_Production_ID" => $db2['ADM_Production_ID'],
                    "Plan_delivery_date" => $db2['Plan_delivery_date'],
                    "created_at" => DB::raw('IFNULL(created_at, NOW())'), // 插入时设为当前时间,更新时保留原值
                    "updated_at" => date('Y-m-d H:i:s') // 每次操作更新时间
                ]
            );
        } 
    }
}

补充说明

  • 如果业务中ADM_Production_ID也是唯一标识,可将查询条件改为["ADM_Production_ID" => $db2['ADM_Production_ID']],或组合多个唯一字段(如["VIN" => $db2['VIN'], "ADM_Production_ID" => $db2['ADM_Production_ID']])
  • 确保wip_tracking表中用于查询的字段(如VIN)已添加唯一索引,避免重复数据并提升查询效率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 19:20:47