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

SQL中如何在MERGE的NOT MATCHED分支插入多行数据?

嘿,这个问题挺常见的——MERGE语句的每个WHEN分支确实只能执行单条操作,所以你没法直接在WHEN NOT MATCHED THEN里一次性插入两行。不过有两种靠谱的方法能实现你的需求,我给你拆解下:

方法1:扩展源数据实现批量插入

思路是先把你的源表@table扩展成每行对应两条记录(一条IsNew=1,一条IsNew=0),然后让MERGE去匹配这些扩展后的记录,这样不匹配的时候就能自动插入两行。

-- 先扩展源数据,每行生成两条不同IsNew的记录
WITH ExtendedSource AS (
    SELECT ID, Content, 1 AS IsNew FROM @table
    UNION ALL
    SELECT ID, Content, 0 AS IsNew FROM @table
)
MERGE ITEMS AS TARGET
USING ExtendedSource AS SOURCE
    -- 匹配条件要加上IsNew,确保同ID的两条记录独立判断
    ON TARGET.[ID] = SOURCE.ID AND TARGET.IsNew = SOURCE.IsNew
WHEN MATCHED THEN
    UPDATE SET TARGET.[Content] = SOURCE.[Content] -- 若记录已存在则更新内容
WHEN NOT MATCHED THEN
    INSERT (ID, Content, TIME, IsNew)
    VALUES (SOURCE.ID, SOURCE.Content, GETDATE(), SOURCE.IsNew);

这个方法的优势是用单条MERGE完成所有操作,逻辑更紧凑,而且天然保证操作的原子性。

方法2:用事务包裹MERGE+单独INSERT

如果不想扩展源数据,也可以用事务把MERGE和INSERT操作绑定起来,确保要么都成功要么都失败,避免数据不一致:

BEGIN TRANSACTION;

-- 先插入IsNew=1的记录
MERGE ITEMS AS TARGET
USING @table AS SOURCE
    ON TARGET.[ID] = SOURCE.ID AND TARGET.IsNew = 1
WHEN MATCHED THEN
    UPDATE SET TARGET.[Content] = SOURCE.Content
WHEN NOT MATCHED THEN
    INSERT (ID, Content, TIME, IsNew)
    VALUES (SOURCE.ID, SOURCE.Content, GETDATE(), 1);

-- 再插入IsNew=0的记录,用NOT EXISTS避免重复
INSERT INTO ITEMS (ID, Content, TIME, IsNew)
SELECT ID, Content, GETDATE(), 0
FROM @table AS SOURCE
WHERE NOT EXISTS (
    SELECT 1 FROM ITEMS AS TARGET
    WHERE TARGET.ID = SOURCE.ID AND TARGET.IsNew = 0
);

COMMIT TRANSACTION;

小提醒

你原语句里的VALUES(ID, TEXT, GETDATE(), 1)应该是笔误吧?TEXT这里应该替换成SOURCE.Content,不然会插入错误的值或者触发语法错误哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:15:59