C# SQL:仅更新与父表值一致的子表数据
实现子表MaterialGroup_Company的条件更新逻辑
这个需求很贴合实际场景——我们只希望那些完全沿用父表旧值的子表行跟着更新,已经做过定制修改的行保持原样。核心思路是先捕获父表更新前的原始值,再关联子表找到匹配旧值的行,最后用父表新值更新这些行。
步骤1:捕获父表的旧值
因为父表更新后原始值就被覆盖了,所以我们需要先把要更新的父表行的旧数据保存下来,用临时表或者表变量都可以。这里以表变量为例(更轻量,适合单会话操作):
DECLARE @OldMaterialGroups TABLE ( ID INT, MaterialGroup_Name VARCHAR(100), MaterialGroup_Price DECIMAL(18,2) -- 如果有更多字段,在这里添加对应的列,比如 MaterialGroup_Desc VARCHAR(200) 等 );
步骤2:更新父表并同步捕获旧值
执行你已经实现的父表更新语句,同时用OUTPUT子句把旧值写入刚才定义的表变量里:
UPDATE MaterialGroup SET MaterialGroup_Name = 'Group 1 - default', -- 你的新名称 MaterialGroup_Price = 45.00 -- 你的新价格 -- 有更多字段的话,在这里继续设置新值 OUTPUT deleted.ID, deleted.MaterialGroup_Name, deleted.MaterialGroup_Price -- 对应添加其他字段的旧值,比如 deleted.MaterialGroup_Desc INTO @OldMaterialGroups WHERE ID = @TargetMaterialGroupID; -- 这里替换成你实际的父表更新条件
步骤3:更新子表中匹配旧值的行
关联子表、表变量(旧值)和更新后的父表(新值),只更新那些子表当前值和父表旧值完全一致的行:
UPDATE mgc SET MaterialGroup_Company_Name = mg_new.MaterialGroup_Name, MaterialGroup_Company_Price = mg_new.MaterialGroup_Price -- 对应添加其他字段的新值赋值,比如 MaterialGroup_Company_Desc = mg_new.MaterialGroup_Desc FROM MaterialGroup_Company mgc JOIN @OldMaterialGroups mg_old ON mgc.MaterialGroup_Default_ID = mg_old.ID JOIN MaterialGroup mg_new ON mgc.MaterialGroup_Default_ID = mg_new.ID -- 关键:子表当前值必须和父表旧值完全匹配,有多少字段就加多少条件 WHERE mgc.MaterialGroup_Company_Name = mg_old.MaterialGroup_Name AND mgc.MaterialGroup_Company_Price = mg_old.MaterialGroup_Price; -- 有更多字段的话,继续添加:AND mgc.MaterialGroup_Company_Desc = mg_old.MaterialGroup_Desc
针对多列场景的注意事项
如果你的实际表有更多需要同步的字段,只需要做两个调整:
- 在
@OldMaterialGroups表变量中添加对应的旧值列 - 在
OUTPUT子句中写入这些字段的旧值 - 在UPDATE子表的
WHERE条件中增加子表字段与父表旧值的匹配判断,同时在SET子句中加入对应的新值赋值
处理NULL值的特殊情况
如果某些字段允许NULL,直接用=匹配会有问题(NULL不等于任何值,包括NULL),可以用数据库的NULL-safe匹配语法:
- SQL Server:
mgc.Field IS NOT DISTINCT FROM mg_old.Field - MySQL:
mgc.Field <=> mg_old.Field - 通用写法:
ISNULL(mgc.Field, '') = ISNULL(mg_old.Field, '')(根据字段类型选择合适的默认值)
这样就能精准匹配那些完全继承默认值、没有做过定制的子表行,而像Company B这种已经修改过的行就会被排除在外,不会被更新。
内容的提问来源于stack exchange,提问作者user3127554
相关产品推荐
相关产品推荐

