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

SQL Server实现批量更新/插入数据的脚本编写咨询

修正后的UPSERT脚本实现方案

我来帮你修正这个脚本,先说说原脚本的问题,再给出两种符合需求的实现方式:

原脚本的核心问题

你的IF EXISTS逻辑是判断临时表中是否存在任意一个retail_id在主表中:

  • 如果有至少一个匹配,就只执行UPDATE,完全忽略那些主表中不存在的id的插入操作;
  • 如果临时表所有id都不在主表,才执行INSERT。

这和你需要的「每个id单独判断:存在则更新,不存在则插入」的需求完全不符。

方法1:使用SQL Server专属的MERGE语句(推荐)

MERGE是专门为这种UPSERT(更新或插入)场景设计的,能在一个语句中完成匹配行的更新和不匹配行的插入,逻辑清晰且效率更高。

MERGE INTO retaildata AS Target
USING massupdate AS Source
ON Target.retail_id = Source.retail_id

-- 当retail_id匹配时,更新Qty和更新日志信息
WHEN MATCHED THEN
    UPDATE SET
        Target.Qty = Source.Qty,
        Target.Last_Updt_User = 'BATCH TRRIGER INSERT/UPDATE',
        Target.Last_Updt_Date = GETDATE()

-- 当retail_id不匹配时,插入完整行数据
WHEN NOT MATCHED THEN
    INSERT (retail_id, Qty, Trigger_Suppress, Next_Ship_Date, Next_Ship_Qty,
            Last_Ship_Date, Last_Ship_Qty, Carrier_Text, Ship_Number, Work_Pack_Code,
            Supplier_Part_Number, Supplier_Inv_Qty, Ship_Comments, Last_Updt_User, Last_Updt_Date)
    VALUES (
        Source.retail_id,
        Source.Qty,
        'N',
        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        'BATCH TRRIGER INSERT/UPDATE',
        GETDATE()
    );

注意事项

  • 确保retail_id是retaildata表的主键或唯一约束,否则MERGE可能会因为匹配到多行而报错;
  • MERGE支持SQL Server 2008及以上版本,如果你的版本更低,可以用下面的方法2。

方法2:分开执行UPDATE和INSERT(更直观)

如果不想用MERGE,也可以先更新所有匹配的行,再插入主表中不存在的行,逻辑同样清晰:

-- 第一步:更新主表中已存在的retail_id对应的Qty和更新日志
UPDATE S
SET
    S.Qty = C.Qty,
    S.Last_Updt_User = 'BATCH TRRIGER INSERT/UPDATE',
    S.Last_Updt_Date = GETDATE()
FROM retaildata S
INNER JOIN massupdate C ON S.retail_id = C.retail_id;

-- 第二步:插入主表中不存在的retail_id对应的完整数据
INSERT INTO retaildata (retail_id, Qty, Trigger_Suppress, Next_Ship_Date, Next_Ship_Qty,
                        Last_Ship_Date, Last_Ship_Qty, Carrier_Text, Ship_Number, Work_Pack_Code,
                        Supplier_Part_Number, Supplier_Inv_Qty, Ship_Comments, Last_Updt_User, Last_Updt_Date)
SELECT
    C.retail_id,
    C.Qty,
    'N',
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    'BATCH TRRIGER INSERT/UPDATE',
    GETDATE()
FROM massupdate C
WHERE NOT EXISTS (
    SELECT 1 FROM retaildata S WHERE S.retail_id = C.retail_id
);

这两种方法都能完美实现你的需求:同步临时表massupdate的数据到主表retaildata,存在则更新,不存在则插入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 00:52:34