PostgreSQL按条件为列赋值失败,添加x≠N判断仍报log对零取值错误
问题原因
你只规避了x = N这一种会导致log入参为0的场景,还有多个隐藏的触发报错的情况:
- PostgreSQL整数除法默认向零取整,当
|N - x| < x时,(N - x)/x的整数除法结果会是0,比如N=3, x=5时,(3-5)/5 = -2/5 = 0,此时log入参为0直接触发报错,哪怕x <> N条件成立 - 若表中存在
x=0的行,只要符合x <> N的过滤条件,计算(N - x)/x会直接触发除以零错误 - PostgreSQL查询优化器可能会提前计算全表的表达式值,哪怕你写了CASE分支或者WHERE过滤条件,也可能提前触发非法值的计算报错
修复方案
写法1:CASE全分支判断(逻辑清晰)
显式判断所有合法计算的前置条件,同时转数值类型避免整数除法截断:
DO $$ DECLARE N integer; BEGIN select count(*) from mytable INTO N; UPDATE words SET measure = CASE WHEN x > 0 AND (N - x) > 0 THEN 1 + log((N - x)::numeric / x::numeric) ELSE 0 END; END $$;
写法2:NULLIF兜底(容错性更高)
用NULLIF拦截所有非法参数,再用COALESCE把异常场景的返回值统一转成0:
DO $$ DECLARE N integer; BEGIN select count(*) from mytable INTO N; UPDATE words SET measure = COALESCE(1 + log(NULLIF((N - x)::numeric / NULLIF(x::numeric, 0), 0)), 0) WHERE x <> N; END $$;
两种写法都从根源上避免了log入参为0或者负数、除以零的问题,不会再触发对应报错。
内容的提问来源于stack exchange,提问作者cruise134
相关产品推荐
相关产品推荐

