Getting number in full 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
Post Reply
User avatar
dr_gori
Moderador
Moderador
Posts: 5024
Joined: Mon, 03 May 2004 3:08 pm
Location: Portland, OR USA
Contact:
Thomas F. G

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

See that interesting:
There is a date format that is represented by numbers. Hence, we ask Oracle to show us this date "by extensive". As a result, we can use this native function to translate numbers to extensive.

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 ... It is no use changing the LANG
* does not accept decimals
* Do not accept very large numbers ....

In summary, this post goes more for curiosity ...
User avatar
dr_gori
Moderador
Moderador
Posts: 5024
Joined: Mon, 03 May 2004 3:08 pm
Location: Portland, OR USA
Contact:
Thomas F. G

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

Is not that Tom Kyte (my Xará), improved this "disability" of large numbers ???
See the function below:

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:

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>  
User avatar
Toad
Rank: DBA Pleno
Rank: DBA Pleno
Posts: 253
Joined: Fri, 18 Nov 2005 2:14 pm
Location: Seattle, WA
Contact:
Matheus Gonçalves
matheus.dev
twitter.com/developer__c

Dr.

I needed to use the extensive in Portuguese in my application.
Using some examples of other languages, I developed the following:

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;
When testing:

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 !!
User avatar
passageiromr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Posts: 7
Joined: Tue, 24 Oct 2006 10:15 am
Location: Santa Cruz do Rio Pardo
Contact:

eae toad, in my case aqui I am doing a tax report, and I am using a schematic in the reports that is & <totalpages>, it returns the total number of pages, I have tmb a procedure called p_extenso, which is very similar to this Above, but I can not associate both things ...
User avatar
passageiromr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Posts: 7
Joined: Tue, 24 Oct 2006 10:15 am
Location: Santa Cruz do Rio Pardo
Contact:

eae toad, in my case aqui I am doing a tax report, and I am using a schematic in the reports that is & <totalpages>, it returns the total number of pages, I have tmb a procedure called p_extenso, which is very similar to this Above, but I can not associate both things ...
User avatar
Toad
Rank: DBA Pleno
Rank: DBA Pleno
Posts: 253
Joined: Fri, 18 Nov 2005 2:14 pm
Location: Seattle, WA
Contact:
Matheus Gonçalves
matheus.dev
twitter.com/developer__c

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

Select all

 
select extenso(var_total_pages) from dual; 
Post Reply
  • Information
  • Who is online

    Users browsing this forum: No registered users and 12 guests