2013-02-12 9 views
1

В Oracle 11.2 существует ли какой-то формат чисел nf, который будет работать с to_number для разбора произвольной длины varchar2s, содержащей цифры и запятые?Oracle 11.2 to_number multiple commas

Я могу добиться этого без числового формата, используя regexp_replace, но я бы предпочел добиться того же, используя только формат чисел.

например, следующие 2 заявления работы:

select to_number(regexp_replace('12,345', ',', '')) from dual; 

select to_number(regexp_replace('1,234,567', ',', '')) from dual; 

, но я бы предпочел:

select to_number('12,345', nf) from dual; 

select to_number('1,234,567', nf) from dual; 

где nf это одна строка Числовой формат, который работает для обоих заявлений.

Если я попробую nf = '99,999', первое утверждение работает, но второе не удается.

Спасибо.

ответ

0

Хотя я поддерживаю ответ Alex Poole, вот еще один сырой, но эффективные способ решения проблемы, который должен работать лучше, чем регулярное выражение.

SQL Fiddle

Oracle 11g R2 Настройка схемы:

CREATE TABLE table_of_numbers (
    example_num VARCHAR2(50) 
) 
/

INSERT INTO table_of_numbers (example_num) 
VALUES ('12,345') 
/

INSERT INTO table_of_numbers (example_num) 
VALUES ('1,234,567') 
/

Запрос 1:

SELECT TO_NUMBER(example_num, RPAD('9', LENGTH(example_num) - 1, '9')) fudge 
FROM table_of_numbers 

Results:

| FUDGE | 
----------- 
| 12345 | 
| 1234567 | 

Если вам нужно совместить запятую, вы можете сделать что-то более сложное с помощью INSTR и LPAD, чтобы убедиться, что вы создаете правильную маску.

0

Для этого:

select to_number('1,234,567', nf) from dual; 

Использование Н.Ф. = 9999999 будет работать.

2

Oracle не будет жаловаться, если формат номера слишком долго, так что вы можете использовать модель, которая имеет достаточно цифр, чтобы справиться с самым большим номером вы можете получить:

SQL> select to_number('12,345', 
    2 '999G999G999G999G999G999G999G999G999G999G999G999G999') from dual; 


TO_NUMBER('12,345','999G999G999G999G999G999G999G999G999G999G999G999G999') 
------------------------------------------------------------------------- 
                    12345 

SQL> select to_number('1,234,567', 
    2 '999G999G999G999G999G999G999G999G999G999G999G999G999') from dual; 

TO_NUMBER('1,234,567','999G999G999G999G999G999G999G999G999G999G999G999G999') 
---------------------------------------------------------------------------- 
                    1234567 

SQL> select to_number('999,999,999,999,999,999,999,999,999,999,999,999,999', 
    2 '999G999G999G999G999G999G999G999G999G999G999G999G999') from dual; 

TO_NUMBER('999,999,999,999,999,999,999,999,999,999,999,999,999','999G999G999G999 
-------------------------------------------------------------------------------- 
                     1.0000E+39 

Я использовал Ggroup separator вместо фиксированной запятой для поддержки глобализации, но эффект тот же.

Единственное ограничение в том, что номер источник должен иметь правильную группировку, чтобы она соответствовала форматированию точно для цифр у него есть:

SQL> select to_number('1,2345', 
    2 '999G999G999G999G999G999G999G999G999G999G999G999G999') from dual; 

select to_number('1,2345', 
       * 
ERROR at line 1: 
ORA-01722: invalid number 
+1

Альтернативное более короткое решение для строк любой поддерживаемой длины: http://stackoverflow.com/a/4143834/603516 – Vadzim

+0

@Vadzim - достаточно забавно, я только что заново изобрел это и собирался добавить его в этот ответ. Но теперь я вижу, что я уже поддержал ответ Винсента, так что, возможно, он скрывался в моей голове ...Возможно, существенные различия заключаются в том, что 'translate' будет работать с последним примером, который я дал, поскольку позиции разделителя не фиксированы, и он будет работать с десятичными знаками. Благодарю. –

Смежные вопросы