Update语句异常语法问题:字段为Null时无法更新
问题拆解与解决办法
原代码里iif(zip<>@zip,@zip,zip)这种写法,初衷应该是想只在字段值和参数值不一样的时候才更新——说白了就是不想做无意义的写入,比如参数和字段值完全一致时,不修改字段,减少数据库的变更日志,或者避免触发不必要的触发器。但这写法有个大坑:当字段本身是NULL的时候,zip<>@zip的结果是UNKNOWN(因为NULL和任何值比较都不成立),所以IIF会返回原来的NULL,哪怕@zip有值也更新不了。
你想直接写zip = @zip完全没问题,但得清楚两种写法的区别:
- 直接赋值
zip = @zip:不管原字段值是什么,都会把@zip的值写进去,哪怕和原字段值一模一样。 - 原IIF写法:只有当原字段和参数值确实不同时才更新,但因为没考虑NULL的情况,逻辑直接崩了。
如果还想保留「只更新不同值」的逻辑,就得把NULL的情况加进去,比如这么改:
修正后的写法(以SQL Server为例)
zip = IIF( (zip <> @zip) OR (zip IS NULL AND @zip IS NOT NULL) OR (zip IS NOT NULL AND @zip IS NULL), @zip, zip )
或者用更简洁的NULLIF写法:
zip = IIF(NULLIF(zip, @zip) IS NOT NULL OR NULLIF(@zip, zip) IS NOT NULL, @zip, zip)
嫌IIF不够清晰的话,用CASE语句更直观:
zip = CASE WHEN zip <> @zip OR (zip IS NULL AND @zip IS NOT NULL) OR (zip IS NOT NULL AND @zip IS NULL) THEN @zip ELSE zip END
最后说结论
- 要是你不在乎“无意义写入”这点,直接写
zip = @zip就完事了,简单还不会踩NULL的坑。 - 要是非得保留原逻辑,必须把NULL的比较补上,不然字段为NULL的时候永远更新不了。
内容的提问来源于stack exchange,提问作者Greg Gum
相关产品推荐
相关产品推荐

