Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Stored function de numero a letras

Estas en el tema de Stored function de numero a letras en el foro de Mysql en Foros del Web. Hola estoy haciendo un stored function para convertir numeros a letras. Encontre el codigo en esta pagina : http://r3xet.blogspot.com/2009/11/ah...ara-poder.html , la cual si la corro ...
  #1 (permalink)  
Antiguo 25/05/2010, 19:13
Avatar de dalyla  
Fecha de Ingreso: septiembre-2005
Mensajes: 135
Antigüedad: 18 años, 7 meses
Puntos: 1
Stored function de numero a letras

Hola estoy haciendo un stored function para convertir numeros a letras. Encontre el codigo en esta pagina : http://r3xet.blogspot.com/2009/11/ah...ara-poder.html, la cual si la corro como tal me marca errores.

Entonces la fui modificando hasta que solo me marca un error que no entiendo :S
en la ultima linea me dice que no puedo usar '' en la linea 115 o bien la linea siguiente a la ultima.

Este es el codigo:

Código PHP:
BEGIN
DECLARE XlnEntero INT;
DECLARE 
XlcRetorno VARCHAR(512);
DECLARE 
XlnTerna INT;
DECLARE 
XlcMiles VARCHAR(512);
DECLARE 
XlcCadena VARCHAR(512);
DECLARE 
XlnUnidades INT;
DECLARE 
XlnDecenas INT;
DECLARE 
XlnCentenas INT;
DECLARE 
XlnFraccion INT;
DECLARE 
Xresultado varchar(512);

SELECT XlnEntero FLOOR(XNumero), 
    
XlnFraccion = (XNumero XlnEntero) * 100
    
XlcRetorno ''XlnTerna ;
    WHILE( 
XlnEntero 0) DO
        
BEGIN /* WHILE */
        
        /* Recorro terna por terna*/
        
SELECT XlcCadena '';
        
SELECT XlnUnidades XlnEntero 10;
        
SELECT XlnEntero FLOOR(XlnEntero/10);
        
SELECT XlnDecenas XlnEntero 10;
        
SELECT XlnEntero FLOOR(XlnEntero/10);
        
SELECT XlnCentenas XlnEntero 10;
        
SELECT XlnEntero FLOOR(XlnEntero/10);

        
/* Analizo las unidades*/
        
SELECT XlcCadena =
            CASE 
/* UNIDADES */
                
WHEN XlnUnidades AND XlnTerna 1 THEN 'UNO ' XlcCadena
                WHEN XlnUnidades 
AND XlnTerna <> 1 THEN 'UN ' XlcCadena
                WHEN XlnUnidades 
2 THEN 'DOS ' XlcCadena
                WHEN XlnUnidades 
3 THEN 'TRES ' XlcCadena
                WHEN XlnUnidades 
4 THEN 'CUATRO ' XlcCadena
                WHEN XlnUnidades 
5 THEN 'CINCO ' XlcCadena
                WHEN XlnUnidades 
6 THEN 'SEIS ' XlcCadena
                WHEN XlnUnidades 
7 THEN 'SIETE ' XlcCadena
                WHEN XlnUnidades 
8 THEN 'OCHO ' XlcCadena
                WHEN XlnUnidades 
9 THEN 'NUEVE ' XlcCadena
                
ELSE XlcCadena
            END
/* UNIDADES */

        /*-- Analizo las decenas*/
        
SELECT XlcCadena =
            CASE 
/* DECENAS */
                
WHEN XlnDecenas 1 THEN
                    
CASE XlnUnidades
                        WHEN 0 THEN 
'DIEZ '
                        
WHEN 1 THEN 'ONCE '
                        
WHEN 2 THEN 'DOCE '
                        
WHEN 3 THEN 'TRECE '
                        
WHEN 4 THEN 'CATORCE '
                        
WHEN 5 THEN 'QUINCE'
                        
ELSE 'DIECI' XlcCadena
                    END
                WHEN XlnDecenas 
AND XlnUnidades 0 THEN 'VEINTE ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades <> 0 THEN 'VEINTI' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades 0 THEN 'TREINTA ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades <> 0 THEN 'TREINTA Y ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades 0 THEN 'CUARENTA ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades <> 0 THEN 'CUARENTA Y ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades 0 THEN 'CINCUENTA ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades <> 0 THEN 'CINCUENTA Y ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades 0 THEN 'SESENTA ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades <> 0 THEN 'SESENTA Y ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades 0 THEN 'SETENTA ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades <> 0 THEN 'SETENTA Y ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades 0 THEN 'OCHENTA ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades <> 0 THEN 'OCHENTA Y ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades 0 THEN 'NOVENTA ' XlcCadena
                WHEN XlnDecenas 
AND XlnUnidades <> 0 THEN 'NOVENTA Y ' XlcCadena
                
ELSE XlcCadena
            END
/* DECENAS */

        /* Analizo las centenas*/
        
SELECT XlcCadena =
            CASE 
/* CENTENAS */
                
WHEN XlnCentenas AND XlnUnidades AND XlnDecenas 0 THEN 'CIEN ' XlcCadena
                WHEN XlnCentenas 
AND NOT(XlnUnidades AND XlnDecenas 0THEN 'CIENTO ' XlcCadena
                WHEN XlnCentenas 
2 THEN 'DOSCIENTOS ' XlcCadena
                WHEN XlnCentenas 
3 THEN 'TRESCIENTOS ' XlcCadena
                WHEN XlnCentenas 
4 THEN 'CUATROCIENTOS ' XlcCadena
                WHEN XlnCentenas 
5 THEN 'QUINIENTOS ' XlcCadena
                WHEN XlnCentenas 
6 THEN 'SEISCIENTOS ' XlcCadena
                WHEN XlnCentenas 
7 THEN 'SETECIENTOS ' XlcCadena
                WHEN XlnCentenas 
8 THEN 'OCHOCIENTOS ' XlcCadena
                WHEN XlnCentenas 
9 THEN 'NOVECIENTOS ' XlcCadena
                
ELSE XlcCadena
            END
/* CENTENAS */

        /* Analizo la terna*/
        
SELECT XlcCadena =
            CASE 
/* TERNA */
                
WHEN XlnTerna 1 THEN XlcCadena
                WHEN XlnTerna 
AND (XlnUnidades XlnDecenas XlnCentenas <> 0THEN XlcCadena ' MIL '
                
WHEN XlnTerna AND (XlnUnidades XlnDecenas XlnCentenas <> 0) AND XlnUnidades AND XlnDecenas AND XlnCentenas 0 THEN XlcCadena 'MILLON '
                
WHEN XlnTerna AND (XlnUnidades XlnDecenas XlnCentenas <> 0) AND NOT (XlnUnidades AND XlnDecenas AND XlnCentenas 0THEN XlcCadena ' MILLONES '
                
WHEN XlnTerna AND (XlnUnidades XlnDecenas XlnCentenas <> 0THEN XlcCadena ' MIL MILLONES '
                
ELSE ''
            
END/* TERNA */

        /* Armo el retorno terna a terna */
        
SELECT XlcRetorno XlcCadena XlcRetorno;
        
SELECT XlnTerna XlnTerna 1;
        
END/* WHILE */

    
IF XlnTerna 1 THEN
        SELECT XlcRetorno 
'CERO';
    
    
SELECT Xresultado RTRIM(XlcRetorno) + ' CON ' LTRIM(STR(XlnFraccion,2)) + '/100 ' XMoneda;

RETURN 
Xresultado
END 
como estoy usando navicat para crearlo los encabezados y los parametros de entrada y salida se realizan en otro espacio, pero si tienen dudas en el link los podran ver. Estoy usando mysql 5.0.88 por si sirve de algo.
Y espero este codigo les sirva a muchos

gracias
__________________
Ayudar a mejorar a los demas, es hacerte mejor a ti mismo ; )
  #2 (permalink)  
Antiguo 25/05/2010, 20:03
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Stored function de numero a letras

El problema es que estás tratando de usar un código para SQL Server y trasladarlo a MySQL sin tener en cuenta que los lenguajes procedurales no son compatibles entre diferentes DBMS.
No sólo sucede a nivel de ciertas funciones. Los operadores no se escriben igual en muchos casos, por lo que en realidad hay varios y problemáticos defectos en el script, si pretendes usarlo en MySQL.
Algunos casos:
1) Lo que tienes aquí es un STORED FUNCTION y no un STRORED PROCEDURE. No es lo mismo; una de las diferencias substanciales es que MySQL no admite salidas de resultados fuera del RETURN, por lo que el uso de SELECT como medio de asignación de datos es incorrecto. Otra de sus diferencias es que se debe declara, antes del BEGIN, READS SQL DATA, si vas a acceder a tablas, por ejemplo.

2) El uso de "=" para asignar un valor a una variable o un campo, sólo se produce con SET, y no con SELECT.
Para que se entienda bien:
Código MySQL:
Ver original
  1. SELECT XlcCadena = 'OCHENTA';
no es una asignación, sino una comparación lógica (el valor de XlcCadena con la cadena 'OCHENTA').
Así, esto:
Código MySQL:
Ver original
  1. SELECT XlcCadena =
  2.             CASE /* UNIDADES */
  3.                 WHEN XlnUnidades = 1 AND XlnTerna = 1 THEN 'UNO ' + XlcCadena
  4.                 WHEN XlnUnidades = 1 AND XlnTerna <> 1 THEN 'UN ' + XlcCadena
  5.                 WHEN XlnUnidades = 2 THEN 'DOS ' + XlcCadena
  6.                 WHEN XlnUnidades = 3 THEN 'TRES ' + XlcCadena
  7.                 WHEN XlnUnidades = 4 THEN 'CUATRO ' + XlcCadena
  8.                 WHEN XlnUnidades = 5 THEN 'CINCO ' + XlcCadena
  9.                 WHEN XlnUnidades = 6 THEN 'SEIS ' + XlcCadena
  10.                 WHEN XlnUnidades = 7 THEN 'SIETE ' + XlcCadena
  11.                 WHEN XlnUnidades = 8 THEN 'OCHO ' + XlcCadena
  12.                 WHEN XlnUnidades = 9 THEN 'NUEVE ' + XlcCadena
  13.                 ELSE XlcCadena
  14.             END; /* UNIDADES */
Es en realidad una comparación que intentará devolver un dato (TRUE o FALSE) por fuera del RETURN.

3) Esta sentencia está mal escrita:
Código MySQL:
Ver original
  1. SELECT Xresultado = RTRIM(XlcRetorno) + ' CON ' + LTRIM(STR(XlnFraccion,2)) + '/100 ' + XMoneda ;
En MySQL el operador "+" no está definido para crear cadenas de texto, sino sólo para operar números, por lo que dará error (es el error de la línea 115).
Para crear cadenas sobre la base de segmentos distintos, MySQL tiene una función: CONCAT():
Código MySQL:
Ver original
  1. SET xresultado = CONCAT(RTRIM(XlcRetorno), ' CON ', LTRIM(STR(XlnFraccion,2)), '/100 ', XMoneda );

Por último, ten cuidado con el Navicat. Suele agregar espacios entre el nombre de una función y su primer paréntesis, cosa que MySQL no admite, generando un error de sintaxis difícil de detectar.
Es decir, te transforma esto:
Código MySQL:
Ver original
  1. SET xresultado = CONCAT(RTRIM(XlcRetorno), ' CON ', LTRIM(STR(XlnFraccion,2)), '/100 ', XMoneda );
en esto:
Código MySQL:
Ver original
  1. SET xresultado = CONCAT (RTRIM (XlcRetorno), ' CON ', LTRIM (STR (XlnFraccion,2)), '/100 ', XMoneda );
Lo más difícil de detectar de este problema es que sólo se produce en tiempo de ejecución, y no al generar scripts, por lo que sólo recibes un mensaje de error que nunca puedes determinar porque todo parece estar bien...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 26/05/2010, 11:36
Avatar de dalyla  
Fecha de Ingreso: septiembre-2005
Mensajes: 135
Antigüedad: 18 años, 7 meses
Puntos: 1
Respuesta: Stored function de numero a letras

Bien gracias por la ayuda, la verdad es que si entiendo la diferencia entre procedure y function, lo que pasa es que es la primera que hago o modifico en este caso.

Pero me sirvio de mucho tu ayuda, muchas gracias y aqui esta el codigo por los interesados.

Código PHP:

Create 
FUNCTION letras(Numero NUMERIC(20,2),  XMoneda VARCHAR(100)) RETURNS VARCHAR(512)
DETERMINISTIC

BEGIN
DECLARE XlnEntero INT;
DECLARE 
XlcRetorno VARCHAR(512);
DECLARE 
XlnTerna INT;
DECLARE 
XlcMiles VARCHAR(512);
DECLARE 
XlcCadena VARCHAR(512);
DECLARE 
XlnUnidades INT;
DECLARE 
XlnDecenas INT;
DECLARE 
XlnCentenas INT;
DECLARE 
XlnFraccion INT;
DECLARE 
Xresultado varchar(512);

SET XlnEntero FLOOR(XNumero);
SET XlnFraccion = (XNumero XlnEntero) * 100;
SET XlcRetorno '';
SET XlnTerna ;
    WHILE( 
XlnEntero 0) DO

        
#Recorro terna por terna
        
SET XlcCadena '';
        
SET XlnUnidades XlnEntero MOD 10;
        
SET XlnEntero FLOOR(XlnEntero/10);
        
SET XlnDecenas XlnEntero MOD 10;
        
SET XlnEntero FLOOR(XlnEntero/10);
        
SET XlnCentenas XlnEntero MOD 10;
        
SET XlnEntero FLOOR(XlnEntero/10);

        
#Analizo las unidades
        
SET XlcCadena =
            CASE 
# UNIDADES
                
WHEN XlnUnidades AND XlnTerna 1 THEN CONCAT('UNO 'XlcCadena)
                
WHEN XlnUnidades AND XlnTerna <> 1 THEN CONCAT('UN 'XlcCadena)
                
WHEN XlnUnidades 2 THEN CONCAT('DOS 'XlcCadena)
                
WHEN XlnUnidades 3 THEN CONCAT('TRES 'XlcCadena)
                
WHEN XlnUnidades 4 THEN CONCAT('CUATRO 'XlcCadena)
                
WHEN XlnUnidades 5 THEN CONCAT('CINCO 'XlcCadena)
                
WHEN XlnUnidades 6 THEN CONCAT('SEIS 'XlcCadena)
                
WHEN XlnUnidades 7 THEN CONCAT('SIETE 'XlcCadena)
                
WHEN XlnUnidades 8 THEN CONCAT('OCHO 'XlcCadena)
                
WHEN XlnUnidades 9 THEN CONCAT('NUEVE 'XlcCadena)
                ELSE 
XlcCadena
            END
#UNIDADES

        #Analizo las decenas
        
SET XlcCadena =
            CASE 
#DECENAS
                
WHEN XlnDecenas 1 THEN
                    
CASE XlnUnidades
                        WHEN 0 THEN 
'DIEZ '
                        
WHEN 1 THEN 'ONCE '
                        
WHEN 2 THEN 'DOCE '
                        
WHEN 3 THEN 'TRECE '
                        
WHEN 4 THEN 'CATORCE '
                        
WHEN 5 THEN 'QUINCE'
                        
ELSE CONCAT('DIECI'XlcCadena)
                    
END
                WHEN XlnDecenas 
AND XlnUnidades 0 THEN CONCAT('VEINTE 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades <> 0 THEN CONCAT('VEINTI'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades 0 THEN CONCAT('TREINTA 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades <> 0 THEN CONCAT('TREINTA Y 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades 0 THEN CONCAT('CUARENTA 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades <> 0 THEN CONCAT('CUARENTA Y 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades 0 THEN CONCAT('CINCUENTA 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades <> 0 THEN CONCAT('CINCUENTA Y 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades 0 THEN CONCAT('SESENTA 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades <> 0 THEN CONCAT('SESENTA Y 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades 0 THEN CONCAT('SETENTA 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades <> 0 THEN CONCAT('SETENTA Y 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades 0 THEN CONCAT('OCHENTA 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades <> 0 THEN CONCAT('OCHENTA Y 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades 0 THEN CONCAT('NOVENTA 'XlcCadena)
                
WHEN XlnDecenas AND XlnUnidades <> 0 THEN CONCAT('NOVENTA Y 'XlcCadena)
                ELSE 
XlcCadena
            END
#DECENAS

        # Analizo las centenas
        
SET XlcCadena =
            CASE 
# CENTENAS
                
WHEN XlnCentenas AND XlnUnidades AND XlnDecenas 0 THEN CONCAT('CIEN 'XlcCadena)
                
WHEN XlnCentenas AND NOT(XlnUnidades AND XlnDecenas 0THEN CONCAT('CIENTO 'XlcCadena)
                
WHEN XlnCentenas 2 THEN CONCAT('DOSCIENTOS 'XlcCadena)
                
WHEN XlnCentenas 3 THEN CONCAT('TRESCIENTOS 'XlcCadena)
                
WHEN XlnCentenas 4 THEN CONCAT('CUATROCIENTOS 'XlcCadena)
                
WHEN XlnCentenas 5 THEN CONCAT('QUINIENTOS 'XlcCadena)
                
WHEN XlnCentenas 6 THEN CONCAT('SEISCIENTOS 'XlcCadena)
                
WHEN XlnCentenas 7 THEN CONCAT('SETECIENTOS 'XlcCadena)
                
WHEN XlnCentenas 8 THEN CONCAT('OCHOCIENTOS 'XlcCadena)
                
WHEN XlnCentenas 9 THEN CONCAT('NOVECIENTOS 'XlcCadena)
                ELSE 
XlcCadena
            END
#CENTENAS

        # Analizo la terna
        
SET XlcCadena =
            CASE 
# TERNA
                
WHEN XlnTerna 1 THEN XlcCadena
                WHEN XlnTerna 
AND (XlnUnidades XlnDecenas XlnCentenas <> 0THEN CONCAT(XlcCadena,  'MIL ')
                
WHEN XlnTerna AND (XlnUnidades XlnDecenas XlnCentenas <> 0) AND XlnUnidades AND XlnDecenas AND XlnCentenas 0 THEN CONCAT(XlcCadena'MILLON ')
                
WHEN XlnTerna AND (XlnUnidades XlnDecenas XlnCentenas <> 0) AND NOT (XlnUnidades AND XlnDecenas AND XlnCentenas 0THEN CONCAT(XlcCadena'MILLONES ')
                
WHEN XlnTerna AND (XlnUnidades XlnDecenas XlnCentenas <> 0THEN CONCAT(XlcCadena'MIL MILLONES ')
                ELSE 
''
            
END#TERNA

        #Armo el retorno terna a terna
        
SET XlcRetorno CONCAT(XlcCadenaXlcRetorno);
        
SET XlnTerna XlnTerna 1;
    
END WHILE; # WHILE

    
IF XlnTerna 1 THEN SET XlcRetorno 'CERO'END IF;

SET Xresultado CONCAT(RTRIM(XlcRetorno), ' CON 'LTRIM(XlnFraccion), '/100 'XMoneda);

RETURN 
Xresultado;

END 
Espero que el encabezado este bien ya que a final de cuentas lo termine con navicar

y gracias por tu ayuda, sin eso no creo haberlo terminado muchas gracias de veras.
__________________
Ayudar a mejorar a los demas, es hacerte mejor a ti mismo ; )
  #4 (permalink)  
Antiguo 26/05/2010, 11:45
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Stored function de numero a letras

__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: function, letras, numero, stored
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Tema Cerrado




La zona horaria es GMT -6. Ahora son las 14:49.