Почему ошибка недопустимого числа при работе со строковыми функциями и строковыми данными?

#oracle #oracle11g #string-formatting

#Oracle #oracle11g #форматирование строки

Вопрос:

Используя требование LPAD, все мои выражения являются символами. Почему я получаю ORA-01722: invalid number сообщение?

Я хочу дополнить мое значение varchar2 начальными нулями слева. Все мои airpor_codes имеют размер до трех байт, и я хочу, чтобы в левой панели были начальные нули, если это необходимо.

В этом примере я хочу 0777 и 0LAX .

 /* This works */ 
with numeric_airport_code 
as (select '777' as airport from dual)
select airport,
       to_char(airport,'0000') as to_char_padding,
       lpad(airport,4,'000')    as lpadding
from numeric_airport_code;


/* This gives invalid number error */

with alpha_airport_code
as (select 'LAX' as airport from dual)
select airport,
        to_char(airport,'000') as to_char_padding,
       lpad(airport,4,'000')    as lpadding
from  alpha_airport_code;    
  

Ответ №1:

lpad Проблема не в этом, а в to_char() . Во втором запросе, который вы выполняете:

 to_char('LAX', '000')
  

который сначала пытается выполнить неявное преобразование в число:

 to_char(to_number('LAX'), '000')
  

… и to_number('LAX') конечно, получает ORA-01722. Не имеет смысла вызывать to_char() что-то, что уже является строкой. В лучшем случае вы получите ненужные преобразования, но часто — как здесь — они являются неявными и / или завершаются ошибкой.

Если вы только используете lpad , это делает то, что вы сказали, что хотите:

 with airport_code as (
  select '777' as airport from dual
  union all select 'LAX' as airport from dual
)
select airport,
       lpad(airport, 4, '0') as lpadding
from airport_code;

AIR LPAD
--- ----
777 0777
LAX 0LAX
  

Также обратите внимание, что вам нужен только один ноль в третьем аргументе.

Комментарии:

1. Я не знал, что to_char преобразуется в number перед обратным преобразованием в char. Спасибо за объяснение.

2. @zundarz — существует две версии to_char() ; одна принимает число, другая — дату. Если вы передаете любой другой тип данных, он должен быть неявно преобразован либо в число, либо в дату, иначе соответствующая функция вообще не будет. Если вы передаете строку, это преобразование выполняется в число.