如何编写SQL实现三场景下更新slitting_win并同步旧值至slitting_win2?
问题描述
现有表daily_wastage_follow_up,包含字段slitting_win(Column1)和slitting_win2(Column2),需按以下三个场景执行更新操作:
- 当
slitting_win为NULL或0时,仅更新slitting_win,不修改slitting_win2; - 当更新值与
slitting_win当前值相同时,两列均保持不变; - 当更新值为新值时,将
slitting_win的旧值存入slitting_win2,再更新slitting_win。
当前编写的SQL无法正确实现场景3的逻辑,请求提供可行的解决方案。
当前SQL代码:
DECLARE @select_slitting INT SET @select_slitting = (select slitting_win from daily_wastage_follow_up where date = @date) IF @select_slitting = '' OR @select_slitting IS NULL update daily_wastage_follow_up set slitting_win = @slt where date = @date ELSE IF @select_slitting IN (@select_slitting) update daily_wastage_follow_up set slitting_win = @slt where date = @date ELSE IF @select_slitting NOT IN (SELECT slitting_win2 FROM daily_wastage_follow_up WHERE date=@date) update daily_wastage_follow_up set slitting_win2 = @select_slitting,slitting_win = @slt where date = @date
原SQL问题分析
@select_slitting是INT类型,判断@select_slitting = ''无意义,INT无法存储空字符串,该条件永远不成立;@select_slitting IN (@select_slitting)这个条件恒为真,会直接执行该分支的更新,跳过场景3的判断;- 先查询再更新的方式存在并发风险,查询和更新之间数据可能被其他会话修改,导致逻辑错误。
解决方案
用单条UPDATE语句结合CASE表达式实现所有场景逻辑,避免多次查询和分支判断的问题,同时覆盖所有规则:
UPDATE daily_wastage_follow_up SET slitting_win = CASE -- 场景2:更新值与当前值相同,保持原值 WHEN slitting_win = @slt THEN slitting_win -- 场景1:当前值为NULL或0,更新为新值 WHEN slitting_win IS NULL OR slitting_win = 0 THEN @slt -- 场景3:新值,更新为新值 ELSE @slt END, slitting_win2 = CASE -- 场景2、场景1:保持原值 WHEN slitting_win = @slt OR slitting_win IS NULL OR slitting_win = 0 THEN slitting_win2 -- 场景3:将旧值存入slitting_win2 ELSE slitting_win END WHERE date = @date -- 过滤无需更新的行,避免无意义操作 AND (slitting_win <> @slt OR slitting_win IS NULL OR slitting_win = 0)
逻辑说明
- 场景2:当
slitting_win等于更新值@slt时,两个字段都保持原值,且通过WHERE条件直接过滤这类行,不执行更新; - 场景1:当
slitting_win为NULL或0时,仅更新slitting_win为@slt,slitting_win2保持不变; - 场景3:当更新值是新值(既不等于当前
slitting_win,且当前值不是NULL/0),则将slitting_win的旧值赋值给slitting_win2,同时把slitting_win更新为@slt。
内容的提问来源于stack exchange,提问作者Naz Azhar
相关产品推荐
相关产品推荐

