Getting number in words with TO_CHAR

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
  

Poston Thu, 27 May 2004 10:08 pm

Look at that interesting: there is a date format that is represented by numbers. Hence, we ask for the Oracle show us this date \"in full\". As a result, we can use this native function to translate numbers to extensive.

Code: Select all
dbglufke:SCOTT> select to_char( to_date( 123456, 'J'), 'jsp') from dual
  2  /

TO_CHAR(TO_DATE(123456,'J'),'JSP')
--------------------------------------------------------
one hundred twenty-three thousand four hundred fifty-six

dbglufke:SCOTT>
Disadvantages: * only works in English. No use changing the LANG * does not accept decimals * does not accept very large numbers. ...

In summary, this post will more out of curiosity.
dr_gori
Location: Portland, OR USA

Thomas F. G

Você já respondeu a dúvida de alguém hoje?
http://glufke.net/oracle/search.php?search_id=unanswered

Poston Fri, 20 Aug 2004 11:42 am

It's not that Tom Kyte (my namesake), improved this \"disability\" of big numbers???
See the function below:
Code: Select all
create or replace
function spell_number( p_number in number )
return varchar2
as
type myArray is table of varchar2(255);
l_str myArray := myArray( '',
' thousand ', ' million ',
' billion ', ' trillion ',
' quadrillion ', ' quintillion ',
' sextillion ', ' septillion ',
' octillion ', ' nonillion ',
' decillion ', ' undecillion ',
' duodecillion ' );

l_num varchar2(50) default trunc( p_number );
l_return varchar2(4000);
begin
for i in 1 .. l_str.count
loop
exit when l_num is null;

if ( substr(l_num, length(l_num)-2, 3) <> 0 )
then
l_return := to_char(
to_date(
substr(l_num, length(l_num)-2, 3),
'J' ),
'Jsp' ) || l_str(i) || l_return;
end if;
l_num := substr( l_num, 1, length(l_num)-3 );
end loop;

return l_return;
end;
/
let's test:
Code: Select all
SQL> select spell_number(1234567890) from dual;

SPELL_NUMBER(1234567890)
--------------------------------------------------------
One billion Two Hundred Thirty-Four million Five
Hundred Sixty-Seven thousand Eight Hundred Ninety

SQL>
dr_gori
Location: Portland, OR USA

Thomas F. G

Você já respondeu a dúvida de alguém hoje?
http://glufke.net/oracle/search.php?search_id=unanswered

Poston Fri, 10 Feb 2006 11:15 am

Dr.

I had to use the extensive in Portuguese in my application.
Using some examples from other languages, I developed the following:
Code: Select all
create or replace function extenso_monetario ( valor number ) return varchar2 IS
valor_string varchar2( 256 );
valor_conv VARCHAR2(25);
ind NUMBER;
tres_digitos VARCHAR2(3);
texto_string varchar2(256);
begin
  valor_conv := to_char( trunc((abs(valor) * 100),0) , '0999999999999999999' );
  valor_conv := substr( valor_conv , 1 , 18 ) || '0' || substr( valor_conv , 19, 2 );
  if to_number( valor_conv ) = 0 then
    return( 'Zero ' );
  end if;
  for ind in 1..7 loop
    tres_digitos := substr( valor_conv , (((ind-1)*3)+1) , 3 );
    texto_string := '' ;
    -- Extenso para Centena
    if substr(tres_digitos,1,1) = '2' then
      texto_string := texto_string || 'Duzentos ' ;
    elsif substr(tres_digitos,1,1) = '3' then
      texto_string := texto_string || 'Trezentos ' ;
    elsif substr(tres_digitos,1,1) = '4' then
      texto_string := texto_string || 'Quatrocentos ' ;
    elsif substr(tres_digitos,1,1) = '5' then
      texto_string := texto_string || 'Quinhentos ' ;
    elsif substr(tres_digitos,1,1) = '6' then
      texto_string := texto_string || 'Seiscentos ' ;
    elsif substr(tres_digitos,1,1) = '7' then
      texto_string := texto_string || 'Setecentos ' ;
    elsif substr(tres_digitos,1,1) = '8' then
      texto_string := texto_string || 'Oitocentos ' ;
    elsif substr(tres_digitos,1,1) = '9' then
      texto_string := texto_string || 'Novecentos ' ;
    end if;
    if substr(tres_digitos,1,1) = '1' then
      if substr(tres_digitos,2,2) = '00' then
        texto_string := texto_string || 'Cem ' ;
      else
        texto_string := texto_string || 'Cento ' ;
      end if;
    end if;
    -- Extenso para Dezena
    if substr(tres_digitos,2,1) <> '0' and texto_string is not null then
      texto_string := texto_string || 'e ';
    end if;
    if substr(tres_digitos,2,1) = '2' then
      texto_string := texto_string ||'Vinte ';
    elsif substr(tres_digitos,2,1) = '3' then
      texto_string := texto_string ||'Trinta ';
    elsif substr(tres_digitos,2,1) = '4' then
      texto_string := texto_string ||'Quarenta ';
    elsif substr(tres_digitos,2,1) = '5' then
      texto_string := texto_string ||'Cinquenta ';
    elsif substr(tres_digitos,2,1) = '6' then
      texto_string := texto_string ||'Sessenta ';
    elsif substr(tres_digitos,2,1) = '7' then
      texto_string := texto_string ||'Setenta ';
    elsif substr(tres_digitos,2,1) = '8' then
      texto_string := texto_string ||'Oitenta ';
    elsif substr(tres_digitos,2,1) = '9' then
      texto_string := texto_string ||'Noventa ';
    end if;
    if substr(tres_digitos,2,1) = '1' then
      if substr(tres_digitos,3,1) <> '0' then
        if substr(tres_digitos,3,1) = '1' then
          texto_string := texto_string ||'Onze ';
        elsif substr(tres_digitos,3,1) = '2' then
          texto_string := texto_string ||'Doze ';
        elsif substr(tres_digitos,3,1) = '3' then
          texto_string := texto_string ||'Treze ';
        elsif substr(tres_digitos,3,1) = '4' then
          texto_string := texto_string ||'Catorze ';
        elsif substr(tres_digitos,3,1) = '5' then
          texto_string := texto_string ||'Quinze ';
        elsif substr(tres_digitos,3,1) = '6' then
          texto_string := texto_string ||'Dezesseis ';
        elsif substr(tres_digitos,3,1) = '7' then
          texto_string := texto_string ||'Dezessete ';
        elsif substr(tres_digitos,3,1) = '8' then
          texto_string := texto_string ||'Dezoito ';
        elsif substr(tres_digitos,3,1) = '9' then
          texto_string := texto_string ||'Dezenove ';
        end if;
      else
        texto_string := texto_string ||'Dez ' ;
      end if;
    else
    -- Extenso para Unidade
      if substr(tres_digitos,3,1) <> '0' and texto_string is not null then
        texto_string := texto_string || 'e ';
      end if;
      if substr(tres_digitos,3,1) = '1' then
        texto_string := texto_string ||'Um ';
      elsif substr(tres_digitos,3,1) = '2' then
        texto_string := texto_string ||'Dois ';
      elsif substr(tres_digitos,3,1) = '3' then
        texto_string := texto_string ||'Tres ';
      elsif substr(tres_digitos,3,1) = '4' then
        texto_string := texto_string ||'Quatro ';
      elsif substr(tres_digitos,3,1) = '5' then
        texto_string := texto_string ||'Cinco ';
      elsif substr(tres_digitos,3,1) = '6' then
        texto_string := texto_string ||'Seis ';
      elsif substr(tres_digitos,3,1) = '7' then
        texto_string := texto_string ||'Sete ';
      elsif substr(tres_digitos,3,1) = '8' then
        texto_string := texto_string ||'Oito ';
      elsif substr(tres_digitos,3,1) = '9' then
        texto_string := texto_string ||'Nove ';
      end if;
    end if;
    if to_number( tres_digitos ) > 0 then
      if to_number( tres_digitos ) = 1 then
        if ind = 1 then
          texto_string := texto_string || 'Quatrilhão ' ;
        elsif ind = 2 then
          texto_string := texto_string || 'Trilhão ' ;
        elsif ind = 3 then
          texto_string := texto_string || 'Bilhão ' ;
        elsif ind = 4 then
          texto_string := texto_string || 'Milhão ' ;
        elsif ind = 5 then
          texto_string := texto_string || 'Mil ' ;
        end if;
      else
        if ind = 1 then
          texto_string := texto_string || 'Quatrilhões ' ;
        elsif ind = 2 then
          texto_string := texto_string || 'Trilhões ' ;
        elsif ind = 3 then
          texto_string := texto_string || 'Bilhões ' ;
        elsif ind = 4 then
          texto_string := texto_string || 'Milhões ' ;
        elsif ind = 5 then
          texto_string := texto_string || 'Mil ' ;
        end if;
      end if;
    end if;
    valor_string := valor_string || texto_string;
    -- Escrita da Moeda Corrente
    if ind = 5 then
      if to_number( substr( valor_conv , 16 , 3 )) > 0 and valor_string is
          not null then
        valor_string := rtrim(valor_string) || ', ';
      end if;
    else
      if ind < 5 and valor_string is not null then
        valor_string := rtrim(valor_string) || ', ';
      end if;
    end if;
    if ind = 6 then
      if to_number( substr( valor_conv , 1 , 18 ) ) > 1 then
        valor_string := valor_string || 'Reais ';
      elsif to_number( substr( valor_conv , 1 , 18 ) ) = 1 then
        valor_string := valor_string || 'Real ';
      end if;
     
      if to_number( substr( valor_conv , 20 , 2 ) ) > 0 and
           length(valor_string) > 0  then
        valor_string := valor_string || 'e ';
      end if;
    end if;
    -- Escrita para Centavos
    if ind = 7 then
      if to_number( substr( valor_conv , 20 , 2 ) ) > 1 then
        valor_string := valor_string  || 'Centavos ';
      elsif to_number( substr( valor_conv , 20 , 2 ) ) = 1 then
        valor_string := valor_string  || 'Centavo ';
      end if;
    end if;
  end loop;
  return( rtrim(valor_string) );
exception
  when others then
    return( '*** VALOR INVALIDO ***' );
end;
The test:
Code: Select all
SQL> select extenso_monetario(1) ext from dual;

EXT
----------------------------------------------------------------------------------------------------
Um Real

SQL> select extenso_monetario(1.50) ext from dual;

EXT
----------------------------------------------------------------------------------------------------
Um Real e Cinquenta Centavos

SQL> select extenso_monetario(0.85) ext from dual;

EXT
----------------------------------------------------------------------------------------------------
Oitenta e Cinco Centavos

SQL> select extenso_monetario(785412698.58) ext from dual;

EXT
----------------------------------------------------------------------------------------------------
Setecentos e Oitenta e Cinco Milhões, Quatrocentos e Doze Mil, Seiscentos e Noventa e Oito Reais e Cinquenta e Oito Centavos
:-

Hugs!!
Toad
Location: Seattle, WA

Matheus H. Gonçalves
www.toad.com.br
www.twitter.com/toadgeek

Poston Tue, 24 Oct 2006 11:08 am

eae toad, in my case I'm making a tax report aqui, and am using a schema in the reports which is the <totalpages> &, he returns the total number of pages, have a procedure called P_EXTENSO tmb, which is very similar to that above, but I am not able to associate the two things ...
passageiromr
Location: Santa Cruz do Rio Pardo

Poston Tue, 24 Oct 2006 11:09 am

eae toad, in my case I'm making a tax report aqui, and am using a schema in the reports which is the <totalpages> &, he returns the total number of pages, have a procedure called P_EXTENSO tmb, which is very similar to that above, but I am not able to associate the two things ...
passageiromr
Location: Santa Cruz do Rio Pardo

Poston Tue, 24 Oct 2006 11:38 am

If it returns the total number of pages, you can apply the function, passing the total number of pages as a parameter of the function.

Code: Select all
select extenso(var_total_pages) from dual;
Toad
Location: Seattle, WA

Matheus H. Gonçalves
www.toad.com.br
www.twitter.com/toadgeek


  • See also
    Replies
    Views
    Last Post


    Return to PL/SQL

    Who is online

    Users browsing this forum: No registered users and 5 guests