2016-09-12 6 views
4

У меня есть два 12c (12.1.0.2.0) базы данных Oracle, один из которых возвращает 'ok' для следующего запроса (с использованием SQL Developer 3.2.20.10), в то время как другие результаты в ORA-01722: invalid number:Oracle NVL недействительный номер

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

документация Oracle для NVL говорит:

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_COMP, NLS_SORT и NLS_LANGUAGE одинаковы между двумя базами данных, поэтому они не должны быть Кау пейте разницу в числовом приоритете двух аргументов. Что может быть разным между этими двумя базами данных, чтобы заставить один возвращать 'ok', а другой - к ошибке?

+0

они одни и те же версии, они на тот же сервер, вы подключаетесь к ним через одного и того же клиента с одного и того же компьютера клиента? – kevinsky

+0

Они оба 12.1.0.2.0 (соответствует версии сервера и клиента). Они находятся на разных серверах. В обоих случаях я подключаюсь к SQL Developer 3.2.20.10. Однако я не подключаюсь к ним с одного и того же клиентского ПК. – hmqcnoesy

+0

Я проверил тест и «выберите nvl (1, '1') из двойных« работает », но« выберите nvl (1, «X») из двойного «нет». Согласно документам oracle он никогда не должен работать, если первый параметр является числовым, а второй параметр не может быть представлен как число. – OldProgrammer

ответ

4

cursor_sharing, вероятно, ключевой фактор.

Предикат «1 = nvl (1, 'X')» может быть оценен во время разбора, если он всегда будет выполняться как литералы и оптимизирован как истинный или ложный. Однако, если 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

Это мило ... это не ответ, но я не могу опубликовать это в комментариях с какой-либо читаемой ясностью.

Это все работает на одном экземпляре (оракул 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

Не знаете, почему это, по-видимому, оценивает NVL по-разному между предложениями WHERE и SELECT.

0

оборачивать параметр столбца для NVL в «to_char» решить мою проблему с «ORA-01722: неправильный номер» ошибка:

select 'ok' from dual where 1 = nvl(to_char(1), 'X'); 
Смежные вопросы