Quando você usa o
TO_CHAR()
para formatar um número no Oracle, você usa um modelo de formato para determinar como o número deve ser formatado. Por exemplo, você pode formatar um número como
12,345.00
ou curta 12,345.00
, dependendo da sua localidade. O modelo de formato pode incluir o
G
ou D
elementos de formato para adicionar uma vírgula a um número. Qual deles você usa depende se você deseja a vírgula como separador de milhares ou como caractere decimal. Alternativamente, você pode usar um caractere de vírgula real (
,
) se você preferir, embora este método não tenha reconhecimento de localidade como o G
e D
elementos de formato são. O G
e D
Elementos de formato
Aqui está um exemplo para demonstrar o
G
e D
elementos de formato:SELECT TO_CHAR(12345, 'fm99G999D00')
FROM DUAL;
Resultado:
12,345.00
Nesse caso, o separador de grupo gera uma vírgula e o caractere decimal gera um ponto. Isso porque o
NLS_TERRITORY
da minha sessão atual parâmetro está definido como Australia
. Veja o que acontece se eu alterar meu
NLS_TERRITORY
parâmetro para Germany
:ALTER SESSION SET NLS_TERRITORY = 'Germany';
SELECT TO_CHAR(12345, 'fm99G999D00')
FROM DUAL;
Resultado:
12,345.00
Agora a vírgula está sendo usada para o caractere decimal.
Como um rápido explicador do modelo de formato acima:
- O
fm
O modificador de formato suprime qualquer preenchimento que possa ser aplicado ao resultado. - O
9
caracteres representam números. - O
0
caractere representa números sem suprimir nenhum zero à esquerda ou à direita.
Aqui está uma lista completa de elementos de formato numérico que você pode usar como referência rápida.
Tele NLS_NUMERIC_CHARACTERS
Parâmetro
Quando definimos o
NLS_TERRITORY
(como no exemplo anterior), isso define implicitamente vários outros parâmetros, incluindo o NLS_NUMERIC_CHARACTERS
parâmetro. Tele
NLS_NUMERIC_CHARACTERS
O parâmetro determina quais caracteres são usados para o separador de grupo e o caractere decimal. Podemos consultar os
V$NLS_PARAMETERS
view para ver quais caracteres estão sendo usados para o separador de grupo e o caractere decimal:SELECT VALUE
FROM V$NLS_PARAMETERS
WHERE PARAMETER = 'NLS_NUMERIC_CHARACTERS';
Resultado:
,.
Aqui vemos que o caractere decimal é representado por uma vírgula, e o separador de grupo é representado por um ponto.
Você pode alterar o valor do
NLS_NUMERIC_CHARACTERS
parâmetro diretamente se você quiser (ou seja, sem alterar o NLS_TERRITORY
parâmetro). ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,';
SELECT TO_CHAR(12345, 'fm99G999D00')
FROM DUAL;
Resultado:
12,345.00
Mas você provavelmente deve evitar fazer isso, porque causa uma desconexão entre os parâmetros NLS. Seus parâmetros NLS não refletem mais os valores padrão para o território atual. A menos que você tenha um bom motivo para não fazê-lo, geralmente é melhor alterar o
NLS_TERRITORY
parâmetro para o território relevante, para que outros parâmetros também possam ser atualizados para seu padrão para o novo território. O 'nlsparam'
Argumento
Uma coisa que devo mencionar é que o
T0_CHAR()
A função aceita um terceiro argumento que permite definir temporariamente vários parâmetros NLS, incluindo o NLS_NUMERIC_CHARACTERS
parâmetro. Quando você faz isso no nível da função, isso não altera o valor desses parâmetros para a sessão atual. Aqui está um exemplo:
ALTER SESSION SET NLS_TERRITORY = 'Germany';
SELECT
TO_CHAR(12345, 'fm99G999D00') AS "r1",
TO_CHAR(
12345, 'fm99G999D00',
'NLS_NUMERIC_CHARACTERS = ''.,'''
) AS "r2",
TO_CHAR(12345, 'fm99G999D00') AS "r3"
FROM DUAL;
Resultado:
r1 r2 r3 ____________ ____________ ____________ 12.345,00 12,345.00 12.345,00
Aqui, configurei o território da sessão para a Alemanha e chamei
TO_CHAR()
três vezes. - A primeira chamada usa os parâmetros NLS da sessão. Isso significa que o separador de grupo padrão é um ponto.
- Na segunda chamada, defini explicitamente meu próprio
NLS_NUMERIC_CHARACTERS
parâmetro de dentro da função. Nesse caso, defino o separador de grupo como uma vírgula. Fazer isso não afetou os parâmetros NLS da minha sessão, conforme visto na terceira chamada. - A terceira chamada usa os parâmetros NLS da sessão, assim como a primeira chamada. Como podemos ver, o separador de grupo e o caractere decimal não foram afetados pela mudança (temporária) que fizemos em nossa segunda chamada.
Vírgula codificada
Outra maneira de adicionar uma vírgula a um número é codificá-lo em seu modelo de formato.
Exemplo:
ALTER SESSION SET NLS_TERRITORY = 'Germany';
SELECT TO_CHAR(12345, 'fm99,999.00')
FROM DUAL;
Resultado:
12,345.00
Nesse caso, codifiquei a vírgula e o ponto. Fazer isso ignora o separador de grupo definido no
NLS_NUMERIC_CHARACTERS
parâmetro. Várias Vírgulas
Você pode ter várias vírgulas e/ou separadores de grupo em um modelo de formato.
Exemplo:
ALTER SESSION SET NLS_TERRITORY = 'Australia';
SELECT TO_CHAR(123456789, 'fm999G999G999D00')
FROM DUAL;
Resultado:
123,456,789.00
Colocação de vírgula inválida
Uma vírgula ou separador de grupo não pode aparecer à direita de um caractere decimal ou ponto em um modelo de formato numérico.
SELECT TO_CHAR(12345, 'fm99D999G00')
FROM DUAL;
Resultado:
Error report - ORA-01481: invalid number format model