Como converter texto em número com eficiência no Oracle PL / SQL com NLS_NUMERIC_CHARACTERS não padrão?

Estou tentando encontrar uma maneira eficiente e genérica de converter de seqüência de caracteres para um número no PL / SQL, onde a configuração local para as configurações NLS_NUMERIC_CHARACTERS é imprevisível - e preferível não vou tocá-la. O formato de entrada é o padrão de programação "123.456789", mas com um número desconhecido de dígitos em cada lado do ponto decimal.

select to_number('123.456789') from dual;
  -- only works if nls_numeric_characters is '.,'

select to_number('123.456789', '99999.9999999999') from dual;
  -- only works if the number of digits in the format is large enough
  -- but I don't want to guess...

to_number aceita um terceiro parâmetro, mas nesse caso você deve especificar um segundo parâmetro também, e não há especificação de formato para "padrão" ...

select to_number('123.456789', null, 'nls_numeric_characters=''.,''') from dual;
  -- returns null

select to_number('123.456789', '99999D9999999999', 'nls_numeric_characters=''.,''') from dual;
  -- "works" with the same caveat as (2), so it's rather pointless...

Há outra maneira de usar PL / SQL:

CREATE OR REPLACE
FUNCTION STRING2NUMBER (p_string varchar2) RETURN NUMBER
IS
  v_decimal char;
BEGIN
  SELECT substr(VALUE, 1, 1)
  INTO v_decimal
  FROM NLS_SESSION_PARAMETERS
  WHERE PARAMETER = 'NLS_NUMERIC_CHARACTERS';
  return to_number(replace(p_string, '.', v_decimal));
END;
/

select string2number('123.456789') from dual;

qual fazexatamente o que eu quero, mas não parece eficiente se você fizer isso muitas e muitas vezes em uma consulta. Você não pode armazenar em cache o valor de v_decimal (buscar uma vez e armazenar em uma variável de pacote) porque ele não sabe se você alterou o valor da sessão para NLS_NUMERIC_CHARACTERS e, em seguida, seria interrompido novamente.

Estou negligenciando alguma coisa? Ou estou me preocupando demais, e a Oracle faz isso muito mais eficiente do que eu acreditaria?

questionAnswers(3)

yourAnswerToTheQuestion