Como converter um numero para texto formatado

Uma das coisas mais básicas que encontramos na programação é a conversão de número para texto formatado. Isto muitas vezes ocorre porque queremos mostrar ao usuário um número fácil de entender separando-o com casas de milhar e decimal. Mas no mundo do SQL infelizmente queries só sabem mostrar o número do jeito que ele é processado, ou seja, 123456789.0987654 não pode ser exibido assim 123.456.789,10 do lado do servidor.

A SQL Function abaixo resolve este problema, ela possui quadro parâmetros de entrada, sendo três deles opcionais:

  • Parâmetro 1: Valor, por exemplo, 123456789.0987654
  • Parâmetro 2: Se for usado, indica o numero de casas para arredondamento, ex: GET_FORMAT_FLOAT(123456789.0987654, 2) retornará 123.456.789,10. Se usar numero negativo, o arredondamento passará a ser feito na porção inteira do numero, ex: GET_FORMAT_FLOAT(123456789.0987654, -2) retornará 123.456.800 (sem parte fração).
  • Parâmetro 3: Se for usado, indicará o separador de milhar, ex: ‘.’.
  • Parâmetro 4: Se for usado, indicará o separador de decimal, ex: ‘.’.

Se gostou dela, pode usufruir:

create or alter function GET_FORMAT_FLOAT (
    P_VALUE double precision,
    P_ROUND integer = -255,
    P_SEP_MILHAR varchar(1)='.',
    P_SEP_DECIMAL varchar(1)=',')
returns varchar(255)
as
declare variable lvalue_as_text varchar(255);
declare variable ltemp_var varchar(255);
declare variable i int;
declare variable lchar varchar(1);
declare variable ltext_int varchar(255);
declare variable ltext_decimal varchar(255);
begin
  /* essa função retorna uma string com numero formatado a partir de um valor
     qualquer, por exemplo, 123456789.0987654 retorna '123.456.789,0987654'.
   O segundo parametro P_ROUND é para indicar arredondamento de casas, ex:
   a=GET_FORMAT_FLOAT(123456789.0987654, 2); -- retorna '123.456.789,10'
   Se o segundo parametro for negativo então o arredondamento será a partir
   dos numeros inteiros e não há mais fração, ex:
   a=GET_FORMAT_FLOAT(123456789.0987654, -2); -- retorna '123.456.800'
   Os parametros P_SEP_MILHAR e P_SEP_DECIMAL servem para indicar o separador
   de milhar e decimal. Exceto o parametro de valor, todos os demais são opcionais
   by gladiston.santana[em]gmail.com
  */
  if (:p_round<>-255) then
  begin
    lvalue_as_text=trim(cast(round(p_value, p_round) as varchar(255)));
  end
  else
  begin
    lvalue_as_text=trim(cast(p_value as varchar(255)));
  end
  -- a parte decimal deve estar separada, geralmente o decimal é '.' nessas
  -- conversões, mas hipoteticamente se não encontrar então procura por ','
  -- antes de decidir que se trata dum numero inteiro
  ltext_decimal='';
  i=position ('.' in lvalue_as_text);
  if (i=0) then
    i=position (',' in lvalue_as_text);
  if (i>0) then
  begin
    -- separando a parte fracionaria
    ltext_decimal=right(lvalue_as_text, char_length(lvalue_as_text)-i);
    lvalue_as_text=left(lvalue_as_text, i-1);
  end
  -- Iniciará um loop do primeiro ao ultimo caractere na parte inteira
  -- acrescentando a milhar a cada 3 caracteres
  ltext_int='';
  ltemp_var=reverse(lvalue_as_text);
  i=0;
  while (i<char_length(ltemp_var)) do
  begin
    i=i+1;
    lchar=substring(ltemp_var from i for 1);
    ltext_int=ltext_int||lchar;
    if (mod(i,3)=0)then
    begin
      -- não coloco milhar quando coincidir com o ultimo caractere
      if (i<>char_length(ltemp_var))
        then ltext_int=ltext_int||p_sep_milhar;
    end
  end
  lvalue_as_text=reverse(ltext_int);
  if (ltext_decimal<>'')
    then lvalue_as_text=lvalue_as_text||p_sep_decimal||ltext_decimal;

  return :lvalue_as_text;
end