SQL Server 2017 使用Merge同步源目标表数据报错求助
错误排查与修正代码
核心语法&逻辑错误列表
- 缺失
MERGE关键字开头,未声明目标表对应TARGET别名,SQL无法识别你要操作的目标表 - 变量
@rqt的赋值语句语法错误(SET后未写变量名),且这段动态SQL完全未执行、和后续合并逻辑无关联,属于冗余代码 - 匹配键(
NoContratAdhesion/NoAvenant/CodeRG)是关联条件,匹配成功后无需重复更新这三个字段 OUTPUT子句取Source.NoContratAdhesion存在空值风险:执行WHEN NOT MATCHED BY SOURCE删除逻辑时无对应源表行,Source字段值为NULL- 末尾额外的
DELETE语句逻辑完全错误:MERGE已经完成了源表不存在的目标数据删除操作,额外删除会误删正常匹配/插入的数据
修正后完整代码
DECLARE @T TABLE(NoContratAdhesion char(8) ); -- 声明MERGE目标表,指定TARGET别名 MERGE infocentre.[dbo].[TCtrCollRG] AS TARGET USING ( SELECT * FROM SSIS_Temp.dbo.Tmp_CollRG_sans_cle_HUM WHERE Flag_doublons <> '1' ) AS SOURCE ON ( TARGET.Nocontratadhesion = SOURCE.NoContratAdhesion AND TARGET.NoAvenant = SOURCE.NoAvenant AND TARGET.CodeRG = SOURCE.CodeRG ) WHEN NOT MATCHED BY TARGET THEN INSERT ( [NoContratAdhesion], [NoAvenant], [NoAdherent], [CodeProduitCible], [CodeRG], [Optionnel], [Retenu], [Retarde], [DateDebutValiditeRG], [DateFinValiditeRG], [DateMajRG], [DateInsertPl], [DateMajPl], Date_CHARG_SIAD, FLAG_DELTA ) VALUES ( SOURCE.[NoContratAdhesion], SOURCE.[NoAvenant], NULL, SOURCE.[CodeProduitCible], SOURCE.[CodeRG], SOURCE.[Optionnel], SOURCE.[Retenu], SOURCE.[Retarde], SOURCE.[DateDebutValiditeRG], SOURCE.[DateFinValiditeRG], SOURCE.[DateMajRG], SOURCE.[DateInsertPl], SOURCE.[DateMajPl], GETDATE(), 'I' ) WHEN MATCHED THEN UPDATE SET -- 匹配键无需重复更新,移除三个关联字段的赋值 TARGET.[NoAdherent] = NULL ,TARGET.[CodeProduitCible] = SOURCE.[CodeProduitCible] ,TARGET.[Optionnel] = SOURCE.[Optionnel] ,TARGET.[Retenu] = SOURCE.[Retenu] ,TARGET.[Retarde] = SOURCE.[Retarde] ,TARGET.[DateDebutValiditeRG] = SOURCE.[DateDebutValiditeRG] ,TARGET.[DateFinValiditeRG] = SOURCE.[DateFinValiditeRG] ,TARGET.[DateMajRG] = SOURCE.[DateMajRG] ,TARGET.[DateInsertPl] = SOURCE.[DateInsertPl] ,TARGET.[DateMajPl] = SOURCE.[DateMajPl] ,TARGET.Date_CHARG_SIAD = GETDATE() ,TARGET.FLAG_DELTA = 'M' WHEN NOT MATCHED BY SOURCE THEN DELETE -- 如果需要捕获被删除的合同编号,用deleted系统表取值 OUTPUT deleted.NoContratAdhesion INTO @T; -- 如果你需要统计操作记录可以查询@T,不需要额外删除目标表数据 -- SELECT * FROM @T; SELECT COUNT(*) FROM infocentre.[dbo].[TCtrCollRG];
额外注意事项
- 执行前请先备份目标表数据,避免删除逻辑误操作导致数据丢失
- 建议先把
DELETE逻辑注释,用OUTPUT验证要删除的数据符合预期后再正式执行
内容的提问来源于stack exchange,提问作者hest
相关产品推荐
相关产品推荐

