天天看點

對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  ;

         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

  3  select '0' a2, 1 a1 from dual

select 1 a1,'0' a2 from dual

union

select '0' a2, 1 a1 from dual

ora-01790: 表達式必須具有與對應表達式相同的資料類型

而從說明了union其實是按列出現的順序進行合并的,并不是按别名.對union的意思了解不對危害很大,從上面的列來說他本來的意思是a2應該為0,但因為他的順序寫錯了結果變成了1。這種危害太大了,如果這些數字是錢本來應該為0的,結果因為查詢中列的順序寫錯了,就會造成巨大的損失。