2016-09-12 86 views
4

我有兩個甲骨文12C(12.1.0.2.0)數據庫,其中一個在ORA-01722: invalid number以下查詢(使用SQL開發3.2.20.10)返回'ok',而其他結果:甲骨文NVL無效號碼

select 'ok' from dual where 1 = nvl(1, 'X'); 

NVL Oracle文檔說:

If expr1 is numeric, then Oracle determines which argument has the highest numeric precedence, implicitly converts the other argument to that datatype, and returns that datatype.

NLS_COMPNLS_SORTNLS_LANGUAGE的值是兩個數據庫之間是相同的,所以他們不應該被CAU在2個參數的數字優先級上發揮不同的作用。這兩個數據庫之間可能有什麼不同,導致返回'ok'和一個出錯?

+0

他們是相同的版本,是他們對同一臺服務器,您是否通過同一臺客戶機上的相同客戶機連接到它們? – kevinsky

+0

它們都是12.1.0.2.0(服務器和客戶端版本匹配)。他們在不同的服務器上。在這兩種情況下,我都與SQL Developer 3.2.20.10連接。但是,我沒有從同一臺客戶端PC連接到它們。 – hmqcnoesy

+0

我跑了一個測試,「從雙」作品,但「選擇nvl(1,'1')從雙」選擇nvl(1,'X')「不。根據oracle文檔,如果第一個參數是數字,則第二個參數不能用數字表示。 – OldProgrammer

回答

4

cursor_sharing可能是關鍵因素。

謂詞「1 = nvl(1,'X')」可以在解析時進行評估,如果它始終以文字形式執行並優化爲true或false。但是,如果cursor_sharing是強制的,那麼所有三個文字都可以替代其他值,並且直到執行時才能評估該表達式。我不得不使用兩個單獨的本地表來測試它。

alter session set cursor_sharing=force; 
create table me_dual as select * from dual; 
select 'ok' from me_dual x where 1 = nvl(1, 'A'); 
select 'ok' from me_dual x where 1 = nvl(1, 'A') 

ERROR at line 1: 
ORA-01722: invalid number 
               * 
alter session set cursor_sharing=exact; 
create table alt_dual as select * from dual; 
select 'ok' from alt_dual x where 1 = nvl(1, 'A'); 

'O 
-- 
ok 
0

這很可愛...這不是一個答案,但我不能以任何可讀性的清晰度發表評論。

這是所有運行在相同的實例(oracle 11)...但我認爲它顯示類似的問題。

SQL> select version from v$instance; 

    VERSION 
    ----------------- 
    11.2.0.4.0 

    SQL> select * from dual where 1 = nvl(1,'X'); 

    D 
    - 
    X 

    SQL> select nvl(1,'X') from dual; 
    select nvl(1,'X') from dual 
       * 
    ERROR at line 1: 
    ORA-01722: invalid number 


    SQL> 

我記得以前看過這個,但不記得怎麼解釋它。 O.o

不確定爲什麼它似乎在WHERE和SELECT子句之間評估NVL的方式不同。

0

包裹列參數NVL內「TO_CHAR」解決了我的問題與「ORA-01722:無效號碼」錯誤:

select 'ok' from dual where 1 = nvl(to_char(1), 'X');