Azure Synapse SQL Merge未更新匹配记录反而重复插入问题排查
Delta Merge操作未更新反而重复插入的根本原因分析
首先贴出对应的代码:
delta_table.alias("target").merge( deduped_df.alias("source"), "trim(upper(target.Id)) = trim(upper(source.dId)) " ).whenMatchedUpdate( set={ "Id" : "source.dId", "EntityId" : "source.EntityId", "PropertyName" : "source.PropertyName", "ValueString":"source.ValueString", "ValueInt" : "source.ValueInt", "ValueDecimal" : "source.ValueDecimal", "ValueBit" : "source.ValueBit", "ValidFrom" : "source.ValidFrom", "ValidTo" : "source.ValidTo", "Description" : "source.Description", "ModifiedBy" : "source.ModifiedBy", "CreatedAt" : "source.CreatedAt", "CreatedBy" : "source.CreatedBy", "Active" : "source.Active", "Saved" : "source.Saved", "ETL_UpdateDate" : "source.ETL_UpdateDate", "ETL_Source" : "source.ETL_Source" } ).whenNotMatchedInsert( values={ "Id" : "source.dId", "EntityId" : "source.EntityId", "PropertyName" : "source.PropertyName", "ValueString":"source.ValueString", "ValueInt" : "source.ValueInt", "ValueDecimal" : "source.ValueDecimal", "ValueBit" : "source.ValueBit", "ValidFrom" : "source.ValidFrom", "ValidTo" : "source.ValidTo", "Description" : "source.Description", "ModifiedBy" : "source.ModifiedBy", "CreatedAt" : "source.CreatedAt", "CreatedBy" : "source.CreatedBy", "Active" : "source.Active", "Saved" : "source.Saved", "ETL_UpdateDate" : "source.ETL_UpdateDate", "ETL_LoadDate" : "source.ETL_LoadDate", "ETL_Source" : "source.ETL_Source" } ).execute()
可能的根本原因如下:
匹配条件未真正命中目标记录:
代码用trim(upper(target.Id)) = trim(upper(source.dId))作为匹配规则,但GUID本身是固定36字符格式,通常不存在大小写或前后空格问题。如果实际数据中存在特殊情况——比如target.Id包含全角空格、source.dId是无连字符的32位GUID、双方GUID格式不统一——trim和upper处理后仍无法匹配,merge会判定为"未匹配",执行插入操作。可以通过将target表与deduped_df执行join,验证是否存在符合条件的匹配行。源数据deduped_df未完成有效去重:
若deduped_df中存在重复的dId值,Delta Lake的merge规则是每个目标行只能被匹配更新一次。第一条source记录匹配并更新target行后,后续相同dId的source记录无法再匹配到该已处理的target行,会触发whenNotMatchedInsert逻辑,导致重复插入。需确认deduped_df的去重逻辑是否生效,确保每个dId仅保留一条记录。目标表Id字段存在数据异常:
若target表的Id字段存储了非标准格式的GUID、或包含不可见控制字符,即使经过trim和upper处理,仍无法与source的dId匹配,导致merge执行插入而非更新。可以查询target表的Id字段,检查数据格式是否统一为标准36字符带连字符的GUID。
内容的提问来源于stack exchange,提问作者Sandeep T
相关产品推荐
相关产品推荐

