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