I\'m trying to find an efficient, generic way to convert from string to a number in PL/SQL, where the local setting for NLS_NUMERIC_CHARACTERS settings is inpredictable -- a
Sorry, I noticed later that your question was for the other way round. Nevertheless it's noteworthy that for the opposite direction there is an easy solution:
A bit late, but today I noticed the special format masks 'TM9' and 'TME' which are described as "the text minimum number format model returns (in decimal output) the smallest number of characters possible." on https://docs.oracle.com/cloud/latest/db112/SQLRF/sql_elements004.htm#SQLRF00210.
It seems as if TM9 was invented just to solve this particular problem:
select to_char(1234.5678, 'TM9', 'NLS_NUMERIC_CHARACTERS=''.,''') from dual;
The result is '1234.5678'
with no leading or trailing blanks, and a decimal POINT despite my environ containing NLS_LANG=GERMAN_GERMANY.WE8MSWIN1252
, which would normally cause a decimal COMMA.
select to_number(replace(:X,'.',to_char(0,'fmd'))) from dual;
btw
select to_number(replace('1.2345e-6','.',to_char(0,'fmd'))) from dual;
and if you want more strict
select to_number(translate(:X,to_char(0,'fmd')||'.','.'||to_char(0,'fmd'))) from dual;
The following should work:
SELECT to_number(:x,
translate(:x, '012345678-+', '999999999SS'),
'nls_numeric_characters=''.,''')
FROM dual;
It will build the correct second argument 999.999999
with the efficient translate
so you don't have to know how many digits there are beforehand. It will work with all supported Oracle number format (up to 62 significant digits apparently in 10.2.0.3).
Interestingly, if you have a really big string the simple to_number(:x)
will work whereas this method will fail.
Edit: support for negative numbers thanks to sOliver.
If you are doing a lot of work per session, an option may be to use ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,' at the beginning of your task.
Of course, if lots of other code is executed in the same session, you may get funky results :-) However we are able to use this method in our data load procedures, since we have dedicated programs with their own connection pools for loading the data.