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.
1 2 3 4 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
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.
1 2 |
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.
1 2 3 |
SELECT PKG_NUMEROS_EN_LETRAS.F_OBT_NUMEROLETRAS(C.SUELDOBASICO) FROM EMPLEADOS C WHERE C.CODIGOEMPLEADO = 53641 |
Gracias, hice un procedimiento pero solo me llegaba hasta 1999999999.00