MERGE语句执行返回‘0行受影响’问题排查求助
问题描述
执行MERGE语句时返回“0行受影响”,具体信息如下:
执行的MERGE语句
MERGE ore as T_Base USING ( SELECT date ,sec ,shift ,id_ore FROM ore WHERE date = '2022-9-20' AND sec = '2' AND shift = '1') AS T_Source ON T_Base.date = T_Source.date AND T_Base.sec = T_Source.sec AND T_Base.shift = T_Source.shift AND T_Base.id_ore = T_Source.id_ore WHEN MATCHED THEN UPDATE SET date = T_Source.date ,sec = T_Source.sec ,shift = T_Source.shift ,id_ore = '1' WHEN NOT MATCHED THEN INSERT (date, sec, shift, id_ore) VALUES (T_Source.date, T_Source.sec, T_Source.shift, '1');
表结构
[id] [int] IDENTITY(1,1) NOT NULL, [date] [datetime] NULL, [sec] [int] NULL, [shift] [int] NULL, [id_ore] [int] NULL
现有数据示例
| id | date | sec | shift | id_ore |
|---|---|---|---|---|
| 11637 | 2022-09-10 00:00:00.000 | 1 | 1 | 13 |
| 11636 | 2022-09-09 00:00:00.000 | 1 | 2 | 13 |
| ... | ... | ... | ... | ... |
预期结果
- 更新场景:
- 无变更时:
id date sec shift id_ore 11637 2022-09-10 00:00:00.000 1 1 13 - 有变更时(更新shift和id_ore):
id date sec shift id_ore 11637 2022-09-10 00:00:00.000 1 2 27
- 无变更时:
- 插入新值场景:
id date sec shift id_ore 11638 2022-09-20 00:00:00.000 1 1 1
原因分析
- 源数据集为空:
USING子句从ore表查询date='2022-9-20' AND sec='2' AND shift='1'的数据,但现有数据中无符合条件的记录,导致T_Source无数据,MERGE自然不会产生任何受影响行。 - 匹配条件冗余:
ON子句包含T_Base.id_ore = T_Source.id_ore,而你要更新的正是id_ore,原表的id_ore必然与源数据不一致,直接阻断了匹配更新的可能。 - 更新操作无实际变更:即便匹配成功,更新的
date、sec、shift与原表值完全相同,数据库会跳过这类无意义更新,不计入受影响行数。
调整方案
根据预期结果,明确MERGE目标后,可按以下方式调整:
场景1:按唯一键更新+插入新记录
以date、sec、shift作为唯一匹配键,更新id_ore;若该键组合不存在,则插入新记录:
MERGE ore as T_Base USING ( -- 替换为实际要更新/插入的数据源,比如固定值或其他表数据 SELECT CAST('2022-09-20' AS datetime) AS date, 2 AS sec, 1 AS shift, 1 AS target_id_ore ) AS T_Source ON T_Base.date = T_Source.date AND T_Base.sec = T_Source.sec AND T_Base.shift = T_Source.shift WHEN MATCHED THEN UPDATE SET id_ore = T_Source.target_id_ore -- 可选:仅当值不同时更新,避免无意义操作 WHERE T_Base.id_ore <> T_Source.target_id_ore WHEN NOT MATCHED THEN INSERT (date, sec, shift, id_ore) VALUES (T_Source.date, T_Source.sec, T_Source.shift, T_Source.target_id_ore);
场景2:批量更新指定现有记录
若仅需更新已有特定条件的记录(如修改date='2022-09-10' AND sec=1 AND shift=1的shift和id_ore),直接用UPDATE更高效:
UPDATE ore SET shift = 2, id_ore = 27 WHERE date = '2022-09-10' AND sec = 1 AND shift = 1;
关键调整总结
- 确保
USING子句返回非空数据集; - 匹配条件仅保留真正的唯一识别键,排除要更新的字段;
- 更新操作仅设置需要变更的字段,或添加条件过滤无变化的行。
内容的提问来源于stack exchange,提问作者Jess163
相关产品推荐
相关产品推荐

