日期:2014-05-16  浏览次数:20513 次

oracle窗口函数+左连接导致的灵异bug
oracle窗口函数导致的灵异bug

现象描述:
oracle存储过程中使用窗口函数累积表中的某一字段,分别在10.2.0.3,10.2.0.4库中进行过详尽测试,没出现过问题,但是上线后出现bug,且稳定复现,分析后确定问题,窗口函数累积出错。

进一步分析发现:sql中OVER PARTITION BY 条件与FROM表的关联条件是相同的三个字段,于是试着调整FROM表的关联条件为另外的PK字段,问题解决。

最开始关联条件的三个字段与调整后的PK字段在维度上是一致的,也就是说,字段A+字段B+字段C就能确定到唯一的一条字段PK,不应该出现这样的问题,本地不能复现,生产环境不能碰,最后只好归结到oracle出现bug上去...


SQL如下:

改前:
select nvl(acc.A, 0) + sum(tf.A) over(partition by tf.pk1, tf.pk2, tf.pk3 order by tf.C)
  from t_temp_flow tf
 inner join t_temp_acccount ta 
         on tf.pk1 = ta.pk1  and tf.pk2 = ta.pk2 and tf.pk3 = ta.pk3
  left join (select * from t_account where corp = :1) acc 
         on pf.pk1 = acc.pk1 and pf.pk2 = acc.pk2 and pf.pk3 = acc.pk3


改后:
select nvl(acc.A, 0) + sum(tf.A) over(partition by tf.pk1, tf.pk2, tf.pk3 order by tf.C)
  from t_temp_flow tf,
       t_temp_acccount ta,
       (select * from t_account where corp = :1) acc
 where tf.pk1 = ta.pk1
   and tf.pk2 = ta.pk2
   and tf.pk3 = ta.pk3
   and ta.pk = acc.pk(+)


维度:pk1+pk2+pk3 = 唯一pk

不知道有没同学遇到过类似问题,partition by的条件 = on的条件时计算混乱的情况。

经过确认:这样的写法确实容易出现问题,项目上线后因为类似的原因爆出另一个bug,竟然在存储过程执行过程中多出6万条数据。解决方案是将操作拆分成两步来完成。

怀疑与oracle现有bug 8278320 Wrong results from CONNECT BY with ORDER BY 类似,但未得到确认,总之,以后尽量不要这么写...