Convertir numeros en Letras en Oracle

Convertir numeros en Letras en Oracle

Crearemos un paquete (package) para poder almacenar nuestros objetos de base de datos (funciones), Las funciones son cenicillas es básicamente códigos PL/SQL  que devolverá un numero expresado en letra.

Quieres saber mas sobre package en oracle sigue este articulo.

Para obtener el resultado favorable hemos creado dos funciones en el cuerpo de paquete (package Body) de los cual se ha declaro como función publica solo una (F_OBT_NUMEROLETRAS), quiere decir que la función (F_OBT_NUMEROLETRAS) es privada y no puede ser utilizada en otros objetos de base de datos.

Creando el Package

Especificación del paquete.

CREATE OR REPLACE PACKAGE PKG_NUMEROS_EN_LETRAS IS
  --OBJETIVO    : FUNCION PARA OBTENER NUMERO CONVERTIDO EN LETRAS 
  FUNCTION F_OBT_NUMEROLETRAS(P_NUMEROENTERO IN NUMBER) RETURN VARCHAR2;
END PKG_NUMEROS_EN_LETRAS;

Cuerpo del paquete

CREATE OR REPLACE PACKAGE BODY PKG_NUMEROS_EN_LETRAS IS
  --RESPONSABLE : JHOON GRANADOS SANTOS
  --FECHA       : 07/11/2018
  --OBJETIVO    : OBTENER NUMEROS CONVERTIDOS EN LETRAS
  --COMENTARIO  : LA FUNCION SOLO SOPORTA HASTA OBTENER BILLONES
  FUNCTION F_OBT_NUMERO_MENOR_MIL(P_NUMEROENTERO IN NUMBER) RETURN VARCHAR2 IS
  
    --RESPONSABLE : JHOON GRANADOS SANTOS
    --FECHA       : 07/11/2018
    --OBJETIVO    : FUNCION PRIVADA PARA OBTENER NUMEROS MENORES A MIL CONVERTIDOS EN LETRAS
  
    FUERA_DE_RANGO EXCEPTION;
    NUMERO_ENTERO  EXCEPTION;
  
    CENTENAS NUMBER;
    DECENAS  NUMBER;
    UNIDADES NUMBER;
  
    V_NUMEROENLETRA VARCHAR2(100);
    UNIR            VARCHAR2(2);
  
  BEGIN
    BEGIN
      IF TRUNC(P_NUMEROENTERO) <> P_NUMEROENTERO THEN
        RAISE NUMERO_ENTERO;
      END IF;
    
      IF P_NUMEROENTERO < 0
         OR P_NUMEROENTERO > 999 THEN
        RAISE FUERA_DE_RANGO;
      END IF;
    
      IF P_NUMEROENTERO = 100 THEN
        RETURN('CIEN ');
      ELSIF P_NUMEROENTERO = 0 THEN
        RETURN('CERO ');
      ELSIF P_NUMEROENTERO = 1 THEN
        RETURN('UNO ');
      ELSE
        CENTENAS := TRUNC(P_NUMEROENTERO / 100);
        DECENAS  := TRUNC((P_NUMEROENTERO MOD 100) / 10);
        UNIDADES := P_NUMEROENTERO MOD 10;
        UNIR     := 'Y ';
      
        -- OBTENIENDO CENTENAS
        IF CENTENAS = 1 THEN
          V_NUMEROENLETRA := 'CIENTO ';
        ELSIF CENTENAS = 2 THEN
          V_NUMEROENLETRA := 'DOSCIENTOS ';
        ELSIF CENTENAS = 3 THEN
          V_NUMEROENLETRA := 'TRESCIENTOS ';
        ELSIF CENTENAS = 4 THEN
          V_NUMEROENLETRA := 'CUATROCIENTOS ';
        ELSIF CENTENAS = 5 THEN
          V_NUMEROENLETRA := 'QUINIENTOS ';
        ELSIF CENTENAS = 6 THEN
          V_NUMEROENLETRA := 'SEISCIENTOS ';
        ELSIF CENTENAS = 7 THEN
          V_NUMEROENLETRA := 'SETECIENTOS ';
        ELSIF CENTENAS = 8 THEN
          V_NUMEROENLETRA := 'OCHOCIENTOS ';
        ELSIF CENTENAS = 9 THEN
          V_NUMEROENLETRA := 'NOVECIENTOS ';
        END IF;
      
        -- OBTENIENDO DECENAS
        IF DECENAS = 3 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'TREINTA ';
        ELSIF DECENAS = 4 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'CUARENTA ';
        ELSIF DECENAS = 5 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'CINCUENTA ';
        ELSIF DECENAS = 6 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'SESENTA ';
        ELSIF DECENAS = 7 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'SETENTA ';
        ELSIF DECENAS = 8 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'OCHENTA ';
        ELSIF DECENAS = 9 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'NOVENTA ';
        ELSIF DECENAS = 1 THEN
          IF UNIDADES < 6 THEN
            IF UNIDADES = 0 THEN
              V_NUMEROENLETRA := V_NUMEROENLETRA || 'DIEZ ';
            ELSIF UNIDADES = 1 THEN
              V_NUMEROENLETRA := V_NUMEROENLETRA || 'ONCE ';
            ELSIF UNIDADES = 2 THEN
              V_NUMEROENLETRA := V_NUMEROENLETRA || 'DOCE ';
            ELSIF UNIDADES = 3 THEN
              V_NUMEROENLETRA := V_NUMEROENLETRA || 'TRECE ';
            ELSIF UNIDADES = 4 THEN
              V_NUMEROENLETRA := V_NUMEROENLETRA || 'CATORCE ';
            ELSIF UNIDADES = 5 THEN
              V_NUMEROENLETRA := V_NUMEROENLETRA || 'QUINCE ';
            END IF;
            UNIDADES := 0;
          ELSE
            V_NUMEROENLETRA := V_NUMEROENLETRA || 'DIECI';
            UNIR            := NULL;
          END IF;
        ELSIF DECENAS = 2 THEN
          IF UNIDADES = 0 THEN
            V_NUMEROENLETRA := V_NUMEROENLETRA || 'VEINTE ';
          ELSE
            V_NUMEROENLETRA := V_NUMEROENLETRA || 'VEINTI';
          END IF;
          UNIR := NULL;
        ELSIF DECENAS = 0 THEN
          UNIR := NULL;
        END IF;
      
        -- OBTENIENDO UNIDADES
        IF UNIDADES = 1 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || UNIR || 'UNO ';
        ELSIF UNIDADES = 2 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || UNIR || 'DOS ';
        ELSIF UNIDADES = 3 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || UNIR || 'TRES ';
        ELSIF UNIDADES = 4 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || UNIR || 'CUATRO ';
        ELSIF UNIDADES = 5 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || UNIR || 'CINCO ';
        ELSIF UNIDADES = 6 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || UNIR || 'SEIS ';
        ELSIF UNIDADES = 7 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || UNIR || 'SIETE ';
        ELSIF UNIDADES = 8 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || UNIR || 'OCHO ';
        ELSIF UNIDADES = 9 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || UNIR || 'NUEVE ';
        END IF;
      END IF;
    
      RETURN(V_NUMEROENLETRA);
    
    EXCEPTION
      WHEN NUMERO_ENTERO THEN
        RETURN('ERROR: EL NUMERO NO ES ENTERO');
      WHEN FUERA_DE_RANGO THEN
        RETURN('ERROR: NUMERO FUERA DE RANGO');
      WHEN OTHERS THEN
        RAISE;
    END;
  END F_OBT_NUMERO_MENOR_MIL;

  FUNCTION F_OBT_NUMEROLETRAS(P_NUMEROENTERO IN NUMBER) RETURN VARCHAR2 IS
  
    --RESPONSABLE : JHOON GRANADOS SANTOS
    --FECHA       : 07/11/2018
    --OBJETIVO    : FUNCION PARA OBTENER NUMERO CONVERTIDO EN LETRAS 
  
    FUERA_DE_RANGO EXCEPTION;
  
    N_MILLARES_DE_MILLON NUMBER;
    N_MILLONES           NUMBER;
    N_MILLARES           NUMBER;
    CENTENAS             NUMBER;
    CENTIMOS             NUMBER;
    V_NUMEROENLETRA      VARCHAR2(2000);
    N_ENTERO             NUMBER;
    AUX                  VARCHAR2(15);
    N_MILLARES_DE_BILLON NUMBER;
  BEGIN
    BEGIN
      IF P_NUMEROENTERO < 0
         OR P_NUMEROENTERO > 999999999999999.99 THEN
        RAISE FUERA_DE_RANGO;
      END IF;
    
      N_ENTERO := TRUNC(P_NUMEROENTERO);
    
      N_MILLARES_DE_BILLON := TRUNC(N_ENTERO / 1000000000000);
    
      N_MILLARES_DE_MILLON := TRUNC(MOD(N_ENTERO, 1000000000000) /
                                    1000000000);
    
      N_MILLONES := TRUNC(MOD(N_ENTERO, 1000000000) / 1000000);
    
      N_MILLARES := TRUNC(MOD(N_ENTERO, 1000000) / 1000);
    
      CENTENAS := MOD(N_ENTERO, 1000);
    
      CENTIMOS := MOD((ROUND(P_NUMEROENTERO, 2) * 100), 100);
    
      -- BILLONES DE MILLON
      IF N_MILLARES_DE_BILLON = 1 THEN
        IF N_MILLARES_DE_MILLON = 0
           OR N_MILLARES_DE_BILLON = 1 THEN
          V_NUMEROENLETRA := 'UN BILLON ';
        ELSE
          V_NUMEROENLETRA := 'BILLON ';
        END IF;
      ELSIF N_MILLARES_DE_BILLON > 1 THEN
      
        V_NUMEROENLETRA := F_OBT_NUMERO_MENOR_MIL(N_MILLARES_DE_BILLON);
      
        IF N_MILLARES_DE_MILLON = 0 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'MIL BILLONES ';
        ELSE
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'BILLONES ';
        END IF;
      
      END IF;
    
      -- MILLARES DE MILLON
    
      IF N_MILLARES_DE_MILLON = 1 THEN
        IF N_MILLONES = 0 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || ' MIL MILLONES ';
        ELSE
          V_NUMEROENLETRA := V_NUMEROENLETRA || ' MIL ';
        END IF;
      ELSIF N_MILLARES_DE_MILLON > 1 THEN
      
        V_NUMEROENLETRA := V_NUMEROENLETRA ||
                           F_OBT_NUMERO_MENOR_MIL(N_MILLARES_DE_MILLON);
      
        IF N_MILLONES = 0 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'MIL MILLONES ';
        ELSE
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'MIL ';
        END IF;
      
      END IF;
    
      -- MILLONES
      IF N_MILLONES = 1
         AND N_MILLARES_DE_MILLON = 0 THEN
        V_NUMEROENLETRA := 'UN MILLON ';
      ELSIF N_MILLONES > 0 THEN
        V_NUMEROENLETRA := V_NUMEROENLETRA ||
                           F_OBT_NUMERO_MENOR_MIL(N_MILLONES) ||
                           'MILLONES ';
      END IF;
    
      -- MILES
      IF N_MILLARES = 1
         AND N_MILLARES_DE_MILLON = 0
         AND N_MILLONES = 0 THEN
        V_NUMEROENLETRA := 'MIL ';
      ELSIF N_MILLARES > 0 THEN
        V_NUMEROENLETRA := V_NUMEROENLETRA ||
                           F_OBT_NUMERO_MENOR_MIL(N_MILLARES) || 'MIL ';
      END IF;
    
      -- CENTENAS
      IF CENTENAS > 0
         OR (N_ENTERO = 0 AND CENTIMOS = 0) THEN
        V_NUMEROENLETRA := V_NUMEROENLETRA ||
                           F_OBT_NUMERO_MENOR_MIL(CENTENAS);
      END IF;
    
      IF CENTIMOS > 0 THEN
        IF N_ENTERO > 0 THEN
          V_NUMEROENLETRA := V_NUMEROENLETRA || 'CON ' ||
                             REPLACE(F_OBT_NUMERO_MENOR_MIL(CENTIMOS),
                                     'UNO ',
                                     'UN ') || AUX;
        ELSE
          V_NUMEROENLETRA := V_NUMEROENLETRA ||
                             REPLACE(F_OBT_NUMERO_MENOR_MIL(CENTIMOS),
                                     'UNO',
                                     'UN') || AUX;
        END IF;
      END IF;
    
      RETURN(V_NUMEROENLETRA);
    
    EXCEPTION
      WHEN FUERA_DE_RANGO THEN
        RETURN('ERROR: NUMERO FUERA DE RANGO');
      WHEN OTHERS THEN
        RAISE;
    END;
  END F_OBT_NUMEROLETRAS;

END PKG_NUMEROS_EN_LETRAS;

Como utilizar el paquete (package) para convertir números en letras

Ejemplo 1.- pasaremos como parametro un numero 2542558.99.

SELECT PKG_NUMEROS_EN_LETRAS.F_OBT_NUMEROLETRAS(2542558.99)
  FROM DUAL;

Resultado:

DOS MILLONES QUINIENTOS CUARENTA Y DOS MIL QUINIENTOS CINCUENTA Y OCHO CON NOVENTA Y NUEVE

Ejemplo 2.– utilizaremos la función dentro de un SELECT, se entiende que el campo a enviar como parámetro debe ser numérico.

SELECT PKG_NUMEROS_EN_LETRAS.F_OBT_NUMEROLETRAS(C.SUELDOBASICO)
  FROM EMPLEADOS C
 WHERE C.CODIGOEMPLEADO = 53641

Referencias:

1 comentario en “Convertir numeros en Letras en Oracle”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.