Ir para o conteúdo principal

Procedure - Retorna valor por extenso

SQL: 

create or alter procedure retorna_valor_por_extenso(valor numeric(15, 2)) returns(valor_extenso varchar(240)) as
declare extenso varchar(240);
declare b1 integer;
declare b2 integer;
declare b3 integer;
declare b4 integer;
declare b5 integer;
declare b6 integer;
declare b7 integer;
declare b8 integer;
declare b9 integer;
declare b10 integer; 
declare b11 integer;
declare b12 integer;
declare b13 integer;
declare b14 integer;
declare l1 varchar(12);
declare l2 varchar(3);
declare l3 varchar(9);
declare l4 varchar(3);
declare l5 varchar(6); 
declare l6 varchar(8);
declare l7 varchar(12);
declare l8 varchar(3);
declare l9 varchar(9);
declare l10 varchar(3);
declare l11 varchar(6);
declare l12 varchar(8);
declare l13 varchar(12);
declare l14 varchar(3); 
declare l15 varchar(9);
declare l16 varchar(3);
declare l17 varchar(6);
declare l18 varchar(8);
declare l19 varchar(12);
declare l20 varchar(3);
declare l21 varchar(9);
declare l22 varchar(3);
declare l23 varchar(6);
declare l24 varchar(16);
declare l25 varchar(3);
declare l26 varchar(9);
declare l27 varchar(3);
declare l28 varchar(6);
declare l29 varchar(17);
declare virgula_bi char(3);
declare virgula_mi char(3);
declare virgula_mil char(3);
declare virgula_cr char(3);
declare valor1 varchar(14);
/*-- tabela de centenas --*/
declare centenas char(108) = 'cento       duzentos    trezentos   quatrocentosquinhentos  seiscentos  setecentos  oitocentos  novecentos  ';
/*-- tabela de dezenas --*/
declare dezenas char(79) = 'dez      vinte    trinta   quarenta cinquentasessenta setenta  oitenta  noventa  '; 
/*-- tabela de unidades --*/
declare unidades char(54) = 'um    dois  tres  quatrocinco seis  sete  oito  nove  ';
/*-- tabela de unidades da dezena 10 --*/
declare unid10   char(81)  = 'onze     doze     treze    quatorze quinze   dezesseisdezessetedezoito  dezenove '; 
declare v_implementar integer;
declare i integer;
declare v_vl_inteiro varchar(14);
begin
  extenso = '';
  l1 = '';
  l2 = '';
  l3 = '';
  l4 = '';
  l5 = '';
  l6 = '';
  virgula_bi = '';
  l7 = '';
  l8 = ''; 
  l9 = '';
  l10 = '';
  l11 = '';
  l12 = '';
  virgula_mi = '';
  l13 = '';
  l14 = '';
  l15 = '';
  l16 = '';
  l17 = ''; 
  l18 = '';
  virgula_mil = '';
  l19 = '';
  l20 = '';
  l21 = '';
  l22 = '';
  l23 = '';
  l24 = '';
  virgula_cr = ''; 
  l25 = '';
  l26 = '';
  l27 = '';
  l28 = '';
  l29 = '';
  i = 1;
  v_implementar = 0;
  v_vl_inteiro = 0;
  
  v_vl_inteiro = valor;
  v_implementar = char_length(v_vl_inteiro);
  valor1 = '';
  while (i <= v_implementar) do
  begin
    if (substring(v_vl_inteiro from i for 1) <> '.') then
    begin
      valor1 = valor1 || substring(v_vl_inteiro from i for 1); 
    end
    i = (i+1);
  end
  v_implementar = (14 - char_length(trim(valor1)));
  i = 0;
  while (i <= v_implementar) do
  begin
    if (char_length(valor1) < 14) then
    begin
      valor1 = '0' || valor1;
    end
    i = (i + 1);
  end
  b1 = substring(valor1 from 1 for 1);
  b2 = substring(valor1 from 2 for 1);
  b3 = substring(valor1 from 3 for 1);
  b4 = substring(valor1 from 4 for 1);
  b5 = substring(valor1 from 5 for 1);
  b6 = substring(valor1 from 6 for 1); 
  b7 = substring(valor1 from 7 for 1);
  b8 = substring(valor1 from 8 for 1);
  b9 = substring(valor1 from 9 for 1);
  b10 = substring(valor1 from 10 for 1);
  b11 = substring(valor1 from 11 for 1);
  b12 = substring(valor1 from 12 for 1); 
  b13 = substring(valor1 from 13 for 1);
  b14 = substring(valor1 from 14 for 1);
  if (valor <> 0) then
  begin
    if (b1 <> 0) then
    begin
      if (b1 = 1) then
      begin
        if ((b2 = 0) and (b3 = 0)) then
        begin
          l5 =  'cem'; 
        end
        else
        begin
          l1 = substring(centenas from (b1 * 12-11) for 12);
        end
      end
      else
      begin
        l1 = substring(centenas from (b1 * 12-11) for 12); 
      end
    end
    if (b2 <> 0) then
    begin
      if (b2 = 1) then
      begin
        if (b3 = 0) then
        begin
          l5 =  'dez';
        end
        else
        begin
          l3 =  substring(unid10 from (b3 * 9-8) for 9); 
        end
      end
      else
      begin
        l3 =  substring(dezenas from (b2 * 9-8) for 9);
      end
    end
    if (b3 <> 0) then
    begin
      if (b2 <> 1) then
      begin
        l5 =  substring(unidades from (b3 * 6-5) for 6);
      end
    end
    if ((b1 <> 0) or (b2 <> 0)  or (b3 <> 0)) then
    begin
      if ((b1 = 0 and b2 = 0) and (b3 = 1)) then 
      begin
        l5 =  'um';
        l6 =  ' bilhão';
      end
      else
      begin
        l6 =  ' bilhões';
      end
      if (valor > 999999999) then
      begin
/*        virgula_bi = ' e ';*/
        virgula_bi = '';
        if ((b4+b5+b6+b7+b8+b9+b10+b11+b12) = 0) then
        begin
          virgula_bi = ' de ' ;
        end 
      end
      l1 =  trim(l1);
      l3 =  trim(l3);
      l5 =  trim(l5);
      if ((b2 > 1) and (b3 > 0)) then
      begin
        l4 = ' e ';
      end
      if ((b1 <> 0) and ((b2 <> 0) or (b3 <> 0))) then 
      begin
        l2 = ' e ';
      end
    end
  /*-- rotina dos milhoes --*/
    if (b4 <> 0) then
    begin
      if (b4 = 1) then
      begin
        if ((b5 = 0) and (b6 = 0)) then
        begin
          l7 =  'cem';
        end 
        else
        begin
          l7 = substring(centenas from (b4 * 12-11) for 12);
        end
      end
      else
      begin
        l7 = substring(centenas from (b4 * 12-11) for 12);
      end 
    end
    if (b5 <> 0) then
    begin
      if (b5 = 1) then
      begin
        if (b6 = 0) then
        begin
          l11 =  'dez';
        end
        else
        begin 
          l9 =  substring(unid10 from (b6 * 9-8) for 9);
        end
      end
      else
      begin
        l9 =  substring(dezenas from (b5 * 9-8) for 9);
      end
    end
    if (b6 <> 0) then 
    begin
      if (b5 <> 1) then
      begin
        l11 =  substring(unidades from (b6 * 6-5) for 6);
      end
    end
    if ((b4 <> 0) or (b5 <> 0)  or (b6 <> 0)) then
    begin
      if (((b4 = 0) and (b5 = 0)) and (b6 = 1)) then
      begin
        l11 =  ' um';
        l12 =  ' milhão';
      end
      else
      begin
        l12 =  ' milhões'; 
      end
      if (valor > 999999) then
      begin
/*        virgula_mi = ' e ';*/
        virgula_mi = '';
        if ((b7+b8+b9+b10+b11+b12) = 0) then
        begin
          virgula_mi = ' de '; 
        end
      end
      l7 =  trim(l7);
      l9 =  trim(l9);
      l11 = trim(l11);
      if ((b5 > 1) and (b6 > 0)) then
      begin
        l10 = ' e ';
      end
      if ((b4 <> 0) and ((b5 <> 0) or (b6 <> 0))) then 
      begin
        l8 = ' e ';
      end
    end
    /*-- rotina dos milhares --*/
    if (b7 <> 0) then
    begin
      if (b7 = 1) then
      begin
        if ((b8 = 0) and (b9 = 0)) then
        begin
          l17 =  'cem';
        end
        else
        begin 
          l13 = substring(centenas from (b7 * 12-11) for 12);
        end
      end
      else
      begin
        l13 = substring(centenas from (b7 * 12-11) for 12);
      end
    end
    if (b8 <> 0) then 
    begin
      if (b8 = 1) then
      begin
        if (b9 = 0) then
        begin
          l17 =  'dez';
        end
        else
        begin
          l15 =  substring(unid10 from (b9 * 9-8) for 9); 
        end
      end
      else
      begin
        l15 =  substring(dezenas from (b8 * 9-8) for 9);
      end
    end
    if (b9 <> 0) then
    begin
      if (b8 <> 1) then
      begin
        l17 =  substring(unidades from (b9 * 6-5) for 6);
      end
    end
    if ((b7 <> 0) or (b8 <> 0)  or (b9 <> 0)) then
    begin
      if (((b7 = 0) and (b8 = 0)) and (b9 = 1)) then 
      begin
        l17 =  'um';
        l18 =  ' mil';
      end
      else
      begin
        l18 =  ' mil';
      end
      if ((valor > 999) and ((b10+b11+b12) <> 0)) then
      begin
        virgula_mil  = ' e ';
      end
      l13 =  trim(l13);
      l15 =  trim(l15);
      l17 =  trim(l17);
      if ((b8 > 1) and (b9 > 0)) then
      begin
         l16 = ' e '; 
      end
      if ((b7 <> 0) and ((b8 <> 0) or (b9 <> 0))) then
      begin
        l14 = ' e ';
      end
    end
  /*-- rotina dos reais --*/
    if (b10 <> 0) then
    begin
      if (b10 = 1) then
      begin
        if ((b11 = 0) and (b12 = 0)) then
        begin
          l19 =  'cem';
        end
        else
        begin 
          l19 = substring(centenas from (b10 * 12-11) for 12);
        end
     end
     else
     begin
       l19 = substring(centenas from (b10 * 12-11) for 12);
     end
    end
    if (b11 <> 0) then
    begin
      if (b11 = 1) then
      begin
        if (b12 = 0) then
        begin
          l23 =  'dez';
        end
        else
        begin
          l21 =  substring(unid10 from (b12 * 9-8) for 9); 
        end
      end
      else
      begin
        l21 =  substring(dezenas from (b11 * 9-8) for 9);
      end
    end
    if (b12 <> 0) then
    begin
      if (b11 <> 1) then 
      begin
        l23 =  substring(unidades from (b12 * 6-5) for 6);
      end
    end
    if ((b10 <> 0) or (b11 <> 0)  or (b12 <> 0)) then
    begin
      if ((valor > 0) and (valor < 2)) then
      begin
        l23 =  'um';
      end
      l19 =  trim(l19); 
      l21 =  trim(l21);
      l23 = trim(l23);
      if ((b11 > 1) and (b12 > 0)) then
      begin
        l22 = ' e ';
      end
      if ((b10 <> 0) and ((b11 <> 0) or (b12 <> 0))) then 
      begin
        l20 = ' e ';
      end
    end
    if ((valor > 0) and (valor < 2))  then
    begin
      if (b12 <> 0) then
      begin
        l24 = ' real';
      end
    end
    else
    begin
      if (valor > 1) then
      begin
        l24 = ' reais';
      end
    end
  /*-- trata centavos --*/
    if ((b13 <> 0) or (b14 <> 0)) then
    begin
      if (valor > 0) then
      begin
        if ((b12 <> 0) or ((b1+b2+b3+b4+b5+b6+b7+b8+b9+b10+b11+b12) <> 0)) then 
        begin
          l25 = ' e ';
        end
      end
      if (b13 <> 0) then
      begin
        if (b13 = 1) then
        begin
          if (b14 = 0) then
          begin 
            l28 =  'dez';
          end
          else
          begin
            l26 =  substring(unid10 from b14*9-8 for 9);
          end
        end
        else
        begin
          l26 =  substring(dezenas from b13*9-8 for 9); 
        end
      end
      if (b14 <> 0) then
      begin
        if (b13 <> 1) then
        begin
          l28 =  substring(unidades from b14*6-5 for 6);
        end
      end
      if ((b13 <> 0)  or (b14 <> 0)) then
      begin
        if (valor = 1) then
        begin
          l28 =  'um';
        end
        l26 =  trim(l26);
        l28 = trim(l28); 
        if ((b13 > 1) and (b14 > 0)) then
        begin
          l27 = ' e ';
        end
      end
      if ((b1+b2+b3+b4+b5+b6+b7+b8+b9+b10+b11+b12) > 0) then
      begin
        if ((b13 = 0) and (b14 = 1)) then 
        begin
          l29 = ' centavo';
        end
        else
        begin
          l29 = ' centavos';
        end
      end
      else
      begin
        if ((b13 = 0) and (b14 = 1)) then 
        begin
          l29 = ' centavo';
        end
        else
        begin
          l29 = ' centavos';
        end
      end
    end
  /*-- concatenar o literal --*/
    if ((l29 = ' centavo') or (l29 = ' centavos')) then
    begin
      virgula_mil = '';
    end
    extenso = iif(trim(l1)='','',trim(l1)||' ')||
              iif(trim(l2)='','',trim(l2)||' ')||
              iif(trim(l3)='','',trim(l3)||' ')||
              iif(trim(l4)='','',trim(l4)||' ')||
              iif(trim(l5)='','',trim(l5)||' ')||
              iif(trim(l6)='','',trim(l6)||' ')||

              iif(trim(virgula_bi)='','',trim(virgula_bi)||' ')||

              iif(trim(l7)='','',trim(l7)||' ')||
              iif(trim(l8)='','',trim(l8)||' ')||
              iif(trim(l9)='','',trim(l9)||' ')||
              iif(trim(l10)='','',trim(l10)||' ')||
              iif(trim(l11)='','',trim(l11)||' ')||
              iif(trim(l12)='','',trim(l12)||' ')||

              iif(trim(virgula_mi)='','',trim(virgula_mi)||' ')||

              iif(trim(l13)='','',trim(l13)||' ')||
              iif(trim(l14)='','',trim(l14)||' ')||
              iif(trim(l15)='','',trim(l15)||' ')||
              iif(trim(l16)='','',trim(l16)||' ')||
              iif(trim(l17)='','',trim(l17)||' ')||
              iif(trim(l18)='','',trim(l18)||' ')||

              iif(trim(virgula_mil)='','',trim(virgula_mil)||' ')||

              iif(trim(l19)='','',trim(l19)||' ')||
              iif(trim(l20)='','',trim(l20)||' ')||
              iif(trim(l21)='','',trim(l21)||' ')||
              iif(trim(l22)='','',trim(l22)||' ')||
              iif(trim(l23)='','',trim(l23)||' ')||
              iif(trim(l24)='','',trim(l24)||' ')||

              iif(trim(virgula_cr)='','',trim(virgula_cr)||' ')||

              iif(trim(l25)='','',trim(l25)||' ')||
              iif(trim(l26)='','',trim(l26)||' ')||
              iif(trim(l27)='','',trim(l27)||' ')||
              iif(trim(l28)='','',trim(l28)||' ')||
              trim(l29);

              extenso = trim(extenso);
  end
  else
  begin
    extenso = 'zero';
  end
  
  valor_extenso = extenso;
  suspend;
  
end

Chamada da procedure: 

SELECT * 
  FROM retorna_valor_por_extenso(65489.64)

Retorno: 

|                                   VALOR_EXTENSO                                       |
-----------------------------------------------------------------------------------------
| sessenta e cinco mil quatrocentos e oitenta e nove reais e sessenta e quatro centavos |