基于指定ParentSnapshotIds的ChildSnapshot与Child表同步Merge语句编写
解决方案
首先修正你提供的表结构中的语法错误(列类型缺失、逗号遗漏、拼写错误):
CREATE TABLE Parent( ParentId int ); CREATE TABLE Child( ChildId int, ParentId int, ColA int ); CREATE TABLE ParentSnapshot( ParentSnapshotId int, ParentId int ); CREATE TABLE ChildSnapshot( ChildSnapshotId int, ParentSnapshotId int, ChildId int, ParentId int, ColA int );
针对给定的ParentSnapshotIds列表,以下是实现同步需求的MERGE语句:
-- 替换@GivenParentSnapshotIds为实际的快照ID列表,比如(1,3,5),或使用表值参数 MERGE INTO ChildSnapshot AS Target USING ( -- 关联原始Child表与目标快照对应的Parent记录 SELECT c.ChildId, c.ParentId, c.ColA, ps.ParentSnapshotId FROM Child c INNER JOIN ParentSnapshot ps ON c.ParentId = ps.ParentId WHERE ps.ParentSnapshotId IN (@GivenParentSnapshotIds) ) AS Source -- 匹配条件:同一快照下的同一条子记录 ON (Target.ChildId = Source.ChildId AND Target.ParentSnapshotId = Source.ParentSnapshotId) -- 匹配时更新字段 WHEN MATCHED THEN UPDATE SET Target.ParentId = Source.ParentId, Target.ColA = Source.ColA -- 原始表存在但快照表不存在时插入 WHEN NOT MATCHED BY TARGET THEN INSERT (ParentSnapshotId, ChildId, ParentId, ColA) VALUES (Source.ParentSnapshotId, Source.ChildId, Source.ParentId, Source.ColA) -- 快照表存在但原始表不存在时删除(仅限定目标快照ID范围) WHEN NOT MATCHED BY SOURCE THEN DELETE WHERE Target.ParentSnapshotId IN (@GivenParentSnapshotIds);
关键逻辑说明
- 关联范围控制:通过
ParentSnapshot表将给定的ParentSnapshotIds映射到对应的ParentId,确保只同步这些父记录下的子数据。 - 精准匹配:
ON子句同时匹配ChildId和ParentSnapshotId,避免不同快照版本的子记录被误匹配。 - 安全删除:
DELETE分支的WHERE条件严格限定在目标快照ID范围内,防止误删其他快照的历史数据。
注意事项
- 若使用动态ID列表,建议用表值参数而非字符串拼接,避免SQL注入风险。
- 确保
ParentSnapshot表中的ParentId与原始Parent表完全一致(快照生成逻辑需保证这一点)。 - 若
ChildSnapshotId是自增主键,插入时无需指定该字段,数据库会自动生成。
内容的提问来源于stack exchange,提问作者Liero
相关产品推荐
相关产品推荐

