2012-03-27 94 views
7

號碼選擇字符串,我發現這個奇怪的行爲,我打破我的大腦與此...任何人有任何想法?作爲甲骨文

的Oracle 10g: 我有兩個不同的表,已經將這一列命名爲 「TESTCOL」 爲VARCHAR2(10),不能爲空。

如果我執行上表1此查詢,我得到正確的結果:

select * from table1 where TESTCOL = 1234; 

注意說我沒有專門放置「1234」 ......這不是一個錯字,這是一個動態生成的查詢,我會盡量不改變它(至少不會在不久的將來)。

但是,如果我運行相同的查詢,對表2,我得到這個錯誤信息:

ORA-01722: Invalid number 

兩個查詢在同一會議上,同一個數據庫中運行。

我一直在該列連接這兩個表,並確定了參加工作,唯一的問題表明,每當我嘗試使用條件。

上,這可能是從一個表不同的其他任何想法?

在此先感謝。

回答

22

如果TESTCOL包含非數字,則在將TESTCOL條目轉換爲數字時,Oracle可能會遇到問題。因爲,它在內部做,是這樣的:

select * from table1 where TO_NUMBER(TESTCOL) = 1234; 

如果你這麼肯定1234不能表示爲VARCHAR文字,那就試試這個相反,爲了比較VARCHAR值,而不是數字的:

select * from table1 where TESTCOL = TO_CHAR(1234); 
3

你正在觸及隱式類型轉換的危險。

對於表達式testcol = 1234,您聲明您要將testcol作爲數字列處理,因此Oracle會嘗試將該列中的所有值轉換爲數字。

發生ORA-01722是因爲顯然該列中至少有一個值是而不是的一個數字。

即使您聲稱這是「不是排字錯誤」它確實是一個。這是一個語法錯誤。

您必須聲明你的參數作爲一個字符串使用單引號:where testcol = '1234'

創建正確的條件是你的問題的唯一解決方案。

4

那麼明顯TABLE2.TESTCOL包含的值,其不是數字。將字符串與數字文字進行比較會生成隱式轉換。所以TESTCOL中的任何值都不能被轉換爲數字將拋出ORA-1722。

因爲您正在比較字符串,所以它沒有打到您比較兩個表的位置。

所以你有幾個選項,你會喜歡的選項。最明顯的答案是清理數據,以便TABLE2不包含非數字。理想情況下,您應該將此列與將列更改爲數字數據類型相結合。否則,您可以更改生成器,以便生成可以針對簡單數據模型運行的代碼。在這種情況下,如果映射列具有字符數據類型,則意味着將文字包裝在引號中。

-1

以下應該工作。只需替換「你的位置」。

select * 
from table1 
where (select TO_NUMBER(TESTCOL) 
     from table2 
     where "your where") = 1234;