sábado, 10 de enero de 2009

numero a literal

Muchas veces se necesita presentar un numero en forma literal es decir en palabras, a continuacion se presenta una funcion que realiza la conversion de un numero entero a palabras 1000 --> "un mil"

POSTGRES SQL
create or replace function numero2literal(_num text) returns text as $$
------------------------
-- Autor: Luis Jordan P.
------------------------

declare
  _literal text;
  _numero text;
begin
  
  _numero:=ltrim(_num,'0');
  _numero:=replace(_numero,',','');
  if length(_numero)=1 then
    SELECT CASE
      WHEN _numero=0 THEN 'cero'
      WHEN _numero=1 THEN 'un'
      WHEN _numero=2 THEN 'dos'
      WHEN _numero=3 THEN 'tres'
      WHEN _numero=4 THEN 'cuatro'
      WHEN _numero=5 THEN 'cinco'
      WHEN _numero=6 THEN 'seis'
      WHEN _numero=7 THEN 'siete'
      WHEN _numero=8 THEN 'ocho'
      WHEN _numero=9 THEN 'nueve'
    ELSE ''
    END INTO _literal;
  end if;
  if length(_numero)=2 then
    SELECT CASE
      WHEN substring(_numero,1,1)=1 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'diez'
        WHEN substring(_numero,2,1)=1 THEN 'once'
        WHEN substring(_numero,2,1)=2 THEN 'doce'
        WHEN substring(_numero,2,1)=3 THEN 'trece'
        WHEN substring(_numero,2,1)=4 THEN 'catorce'
        WHEN substring(_numero,2,1)=5 THEN 'quince'
        WHEN substring(_numero,2,1) between 6 and 9 THEN 'diez y ' || numero2literal(substring(_numero,2,1))
      END  
      WHEN substring(_numero,1,1)=2 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'veinte'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'veinte y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=3 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'treinta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'treinta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=4 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'cuarenta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'cuarenta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=5 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'cincuenta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'cincuenta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=6 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'sesenta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'sesenta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=7 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'setenta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'setenta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=8 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'ochenta'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'ochenta y ' || numero2literal(substring(_numero,2,1))
      END
      WHEN substring(_numero,1,1)=9 THEN CASE
        WHEN substring(_numero,2,1)=0 THEN 'noventa'
        WHEN substring(_numero,2,1) between 1 and 9 THEN 'noventa y ' || numero2literal(substring(_numero,2,1))
      END
    ELSE ''
    END INTO _literal;
  end if;
  if length(_numero)=3 then
    SELECT CASE
      WHEN substring(_numero,1,1)=1 THEN CASE
        WHEN substring(_numero,2,2)='00' THEN 'cien'
        WHEN substring(_numero,2,2)<>'00' THEN 'ciento ' || numero2literal(substring(_numero,2,2))
      END  
      WHEN substring(_numero,1,1) between 2 and 8  THEN CASE
        WHEN substring(_numero,2,2)='00' THEN  numero2literal(substring(_numero,1,1)) || 'cientos'
        WHEN substring(_numero,2,2)<>'00' THEN numero2literal(substring(_numero,1,1)) || 'cientos ' || numero2literal(substring(_numero,2,2))
      END
      WHEN substring(_numero,1,1) = 9  THEN CASE
        WHEN substring(_numero,2,2)='00' THEN  'novecientos'
        WHEN substring(_numero,2,2)<>'00' THEN 'novecientos ' || numero2literal(substring(_numero,2,2))
      END
    ELSE ''
    END INTO _literal;
  end if;
  if length(_numero) between 4 and 6 then
    SELECT numero2literal(substring(_numero,1,length(_numero)-3)) || ' mil' ||
    CASE WHEN substring(_numero, length(_numero)-2,3)='000' THEN ''
    ELSE ' ' || numero2literal(substring(_numero, length(_numero)-2,3))
    END
    INTO _literal;
  end if;
  if length(_numero) between 7 and 12 then  
    SELECT numero2literal(substring(_numero,1,length(_numero)-6)) ||
    CASE WHEN substring(_numero,1,length(_numero)-6) ='1' THEN ' millon'
    ELSE ' millones'
    END
    ||
    CASE WHEN substring(_numero, length(_numero)-5,6)='000000' THEN ''
    ELSE ' ' || numero2literal(substring(_numero, length(_numero)-5,6))
    END
    INTO _literal;
  end if;

  return _literal;
end;
$$ language plpgsql;


select numero2literal('999999999999');

Resultado:
"novecientos noventa y nueve mil novecientos noventa y nueve millones novecientos noventa y nueve mil novecientos noventa y nueve"

No hay comentarios: