2010-02-24 24 views
11

我有一個連接兩個表的查詢。一個表具有varchar類型的列,另一個表具有數字類型。我在3個oracle數據庫上執行了我的查詢,並且看到我希望可以解釋的一些奇怪結果。在兩個數據庫中,像下面這樣的作品。Oracle編號和varchar加入

select a.col1, b.somecol 
from tableA a inner join tableB b on b.col2=a.col1; 

在此查詢中,tableA.col1的類型爲number,tableB.col2的類型爲varchar。這在兩個數據庫中工作正常,但不在第三個。在第三個我得到(ORA-01722)錯誤。第三,我需要做的是這樣......

select a.col1, b.somecol 
from tableA a inner join tableB b on b.col2=to_char(a.col1); 

這適用於所有數據庫。我有這個問題是爲什麼?以上是一個簡化的查詢,真正的查詢稍微複雜一點,可以檢索大量數據,因此第一個版本要快得多。如果我能在所有環境中工作,那將會很棒。

有誰知道爲什麼這可能在某些oracle數據庫中工作,而沒有其他人沒有在數據類型上強制轉換?是否有能夠實現此類行爲的全局設置?

+1

整理將是我的第一個猜測。 Oracle通常允許隱式轉換,所以它可能是一列不通過隱式轉換... – 2010-02-24 23:28:09

+1

您編寫了所有這些單詞,但您仍然無法準確解釋* how *第一個查詢在第三數據庫。 – APC 2010-02-24 23:42:57

+0

對不起,我在第一個查詢中得到一個ORA-01722錯誤,第三個數據庫 – broschb 2010-02-25 00:56:48

回答

15

隱式轉換失敗的一個原因是,連接varchar列包含的數據不是數字。甲骨文處理數爲VARCHAR2加入通過將字符串(看看加里在他的評論中引用),因此它實際上執行這樣的:

select a.col1, b.somecol 
from tableA a inner join tableB b on to_number(b.col2)=a.col1; 

如果tableB.col2包含哪些不是數值 - 似乎很可能,它是一個字符串畢竟 - 然後它會投擲ORA-01722: invalid number。通過將數字列顯式轉換爲字符串,可以縮短Oracle的默認行爲。

事實上,在前兩個環境中沒有遇到這個問題是一個運氣不配置的問題。它可能隨時出現,因爲它只需要一個非數字字符串來打破查詢。所以你真的應該在所有環境中進行明確的轉換。

至於性能,你可以建立一個基於函數的索引...

create index whatever_idx on tableA (to_char(col1)) 
/
+2

稍後http://download.oracle.com/docs/cd/B19306_01/server.102/b14200 /sql_elements002.htm#r16c1-t41 「將字符值與數字值進行比較時,Oracle會將字符數據轉換爲數字值。」 – 2010-02-25 01:07:35

+0

您可以將tableA中的數字轉換爲字符串,以便在tableB中存在非數字字符串時不會出錯。即CAST(a.col1 AS VARCHAR(20)) – 2013-09-11 14:04:02