问题
I have a table with numbers stored as varchar2
with '.' as decimal separator (e.g. '5.92843').
I want to calculate with these numbers using ',' as that is the system default and have used the following to_number
to do this:
TO_NUMBER(number,'99999D9999','NLS_NUMERIC_CHARACTERS = ''.,''')
My problem is that some numbers can be very long, as the field is VARCHAR2(100)
, and when it is longer than my defined format, my to_number
fails with a ORA-01722
.
Is there any way I can define a dynamic number format? I do not really care about the format as long as I can set my decimal character.
回答1:
Is there any way I can define an unlimited number format?
The only way, is to set the appropriate value for nls_numeric_characters
parameter session wide and use to_number()
function without specifying a format mask.
Here is a simple example.Decimal separator character is comma ","
and numeric literals contain period "."
as decimal separator character:
SQL> show parameter nls_numeric_characters;
NAME TYPE VALUE
------------------------------------ ----------- ------
nls_numeric_characters string ,.
SQL> with t1(col) as(
2 select '12345.567' from dual union all
3 select '12.45' from dual
4 )
5 select to_number(col) as res
6 from t1;
select to_number(col)
*
ERROR at line 5:
ORA-01722: invalid number
SQL> alter session set nls_numeric_characters='.,';
Session altered.
SQL> with t1(col) as(
2 select '12345.567' from dual union all
3 select '12.45' from dual
4 )
5 select to_number(col) as res
6 from t1;
res
--------------
12345.567
12.45
回答2:
You can't have "unlimited" number. Maximum precision is 38 significant digits. From the documentation.
回答3:
You might try one of the following approaches (take them for an idea as I do not have a DB for trying it here):
1) Use TO_NUMBER without a format. According to Oracle docs it uses a dot for decimal separator then.
If your number contains group separators, then first remove these and convert then:
TO_NUMBER(TRANSLATE(number, ',''' ,''))
2) Generate the number format from your input:
select TO_NUMBER(n, TRANSLATE(n,' 1,234.567890',TO_CHAR(9999.9, '9G999D9')||'99999'))
from (select '9,876.54' as n from dual);
The latter translates all digits to 9, your group character (here: comma) and your decimal separator (here: dot) to those used by Oracle by default.
来源:https://stackoverflow.com/questions/20196816/dynamic-length-on-number-format-in-to-number-oracle-sql