对union集合操作理解不足造成的巨大的灾难

朋友和我说发现了oracle union操作的一个bug,他的查询语句如下:

SQL> select sum(a1) a1,sum(a2) a2
  2  from (
  3  select 1 a1,0 a2 from dual
  4  union
  5  select 0 a2, 1 a1 from dual
  6  )
  7  ;

        A1         A2
---------- ----------
         1          1


SQL> select 1 a1,0 a2 from dual
  2  union
  3  select 0 a2, 1 a1 from dual
  4  ;

        A1         A2
---------- ----------
         0          1
         1          0

说结果出错了,应该a2为0,他说别名为 a2的值其实是0,说union不是按别名来进行区别的,一开始我还没反应过来。后面想了一下,union的意思是用来合并两条查询的结果并去重,在oracle关于sql的文档中是说union集合操作中的两个查询中的列的类型和个数要相同。例如将上面两个查询别名为a2的值从0改成’0’再执行union操作就会报错:

SQL> select 1 a1,'0' a2 from dual
  2  union
  3  select '0' a2, 1 a1 from dual
  4  ;

select 1 a1,'0' a2 from dual
union
select '0' a2, 1 a1 from dual

ORA-01790: 表达式必须具有与对应表达式相同的数据类型

从而说明了union其实是按列出现的顺序进行合并的,并不是按别名.对union的意思理解不对危害很大,从上面的列来说他本来的意思是a2应该为0,但因为他的顺序写错了结果变成了1。这种危害太大了,如果这些数字是钱本来应该为0的,结果因为查询中列的顺序写错了,就会造成巨大的损失。而朋友的系统就是这么巧就是money,且软件运行了有些年头了。

发表评论

电子邮件地址不会被公开。