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

为何每次执行MERGE语句都会向目标表插入全部数据?

问题分析与解决

核心问题1:Id取反导致匹配永远失败

你的源查询里把Id做了Id * (-1)的处理,这会让源表的Id变成负数,而目标表的Id应该是正常的正数,所以ON source.Id = target.Id这个匹配条件永远不成立,每次执行MERGE时所有源记录都被判定为“目标表中不存在”,自然会全量插入。

核心问题2:缺少修改记录的同步逻辑

当前MERGE只处理了“目标不存在则插入”的场景,没有处理“目标存在但源记录已修改”的更新逻辑,所以即使解决了匹配问题,修改过的记录也同步不了。

额外优化:简化CountryId的查询逻辑

原查询里重复查询了两次源库的Country表,效率很低,可以用JOIN来简化,同时避免嵌套子查询的冗余。

修正后的MERGE语句

MERGE INTO dbo.CountrySourceType AS target
USING (
    SELECT 
        cst.Id,
        cst.Name,
        c.Id AS CountryId
    FROM [192.xxx.x.xxx].WebPortal.dbo.CountrySourceType cst
    JOIN [192.xxx.x.xxx].WebPortal.dbo.Country cs ON cs.Id = cst.CountryId
    JOIN dbo.Country c ON ISNULL(c.Name, '') = ISNULL(cs.Name, '') 
                      AND ISNULL(c.ContinentName, '') = ISNULL(cs.ContinentName, '')
) AS source
ON source.Id = target.Id
WHEN NOT MATCHED BY target THEN
    INSERT ([Name], [CountryId])
    VALUES (source.Name, source.CountryId)
WHEN MATCHED THEN
    UPDATE SET
        target.Name = source.Name,
        target.CountryId = source.CountryId;

修改说明

  • 去掉了Id * (-1)的错误处理,直接使用源表的原始Id,保证匹配条件能正常生效。
  • 新增WHEN MATCHED THEN UPDATE分支,当Id匹配时更新目标表的Name和CountryId字段,同步修改记录。
  • 用JOIN替代嵌套子查询获取CountryId,既简化了代码,又提升了查询效率。
  • 删除了原查询中冗余的WHERE CountryId = cst.CountryId条件(这个条件等价于恒成立,没有过滤作用)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:02:26