none
Que tipo de datos es el de moneda

    Question

  • Quisiera saber como puedo realizar este fomato de dato en sql server2008.

    Ejmplo: 128.00 (ciento veintiocho pesos), 128.50 (ciento veintiocho pesos con cincuenta centavos)

    Lo que deseo realizar es lo siguiente: numero entero - punto - decimal

    Intente con el tipo de dato decimal(18,2) y numeric(18,2), pero el formato que me admite es con una coma Ej: 128,00 (ciento veintiocho pesos), 128,50 (ciento veintiocho pesos con cincuenta centavos).

    Si le coloco un punto a el tipo de dato decimal y numeric, me multiplica el valor. Es que en las facturas digitales de compra que me dan, los precios de compra vienen con un punto y no con una coma, por eso deseo realizar este tipo de dato

    Gracias por su tiempo

    Saturday, October 01, 2011 9:37 PM

Answers

  • Pues me cuesta explicarle un tanto sin referirme a punteros y examinar la memoria RAM directamente (idealmente en C++).  Pero bueno, voy a tratar:

    Un número de punto flotante de tipo float, por ejemplo, es un número que se almacena en 4 bytes.  Esos 4 bytes tratan de representar lo mejor posible el número solicitado (porque a veces no es posible) según los estándares de punto flotante de la IEEE.  Ese número, o sea, esos 4 bytes de memoria, tienen apariencia idéntica en cualquier PC en el mundo, sin importar el idioma en que la PC esté configurada, siempre y cuando la arquitectura de hardware sea la misma (big endian, little endian).

    Ahora lo invito a que relea el párrafo anterior.  Cuénteme:  ¿Encontró usted alguna referencia al símbolo decimal?  La respuesta es No, esos 4 bytes no contienen el símbolo decimal en ninguna parte.  Pues es igual con el tipo de datos double y con el tipo de datos decimal.  Una variable de tipo float representa 4 bytes que representan un número; una variable de tipo double son 8 bytes que representan un número; una variable de tipo decimal son 10 bytes (creo) que representan un número que siempre tiene 4 dígitos decimales (¡¡pero nada de símbolos decimales!!).

    Así que ¿cuándo entra en juego el símbolo decimal?  Cuando el humano quiere LEER el contenido de las variables numéricas en un formato que el humano entiende.  El humano no está acostumbrado a ver la constante de Avogadro cuyo valor es 6,022045e23 (sí, yo uso la coma como símbolo decimal) como una secuencia de 32 números de 1's y 0's, que es el lenguaje de la PC.

    Así que el símbolo decimal únicamente se usa para COMPLACER la vista y el ojo del humano, pero internamente no tiene relevancia alguna en la representación INTERNA en lenguaje de máquina (ceros y unos).  Las máquinas son capaces de almacenar y manipular números de punto flotante sin tener que recurrir nunca a una definición de un separador decimal.  Simplemente no lo ocupan.

    Eso quiere decir que si usted ve un número en su SQL Server con coma porque el servidor está ajustado a utilizar comas como símbolo decimal, eso NO quiere decir que una aplicación .Net en otra PC esté obligada a ENTENDER O DESPLEGAR el valor utilizando la misma convención de símbolo decimal.  ¿Por qué?  Porque SQL Server es capaz de transferir el valor del número de punto flotante en lenguaje de máquina, y el lenguaje de máquina no especifica símbolo decimal alguno, nuevamente, porque no lo necesita.

    ¿Me he explicado mejor?

    Asumiendo que ya me entiende, el símbolo decimal es una mera cuestión COSMÉTICA.  Si usted tiene una variable decimal con un valor, ese valor es correcto en la PC que lo contiene y en el SQL Server en el que se almacena, aún cuando ambas PC's utilicen símbolos decimales distintos.  Esto es posible porque la aplicación .Net transmitirá el valor en lenguaje de máquina que no admite la definición de algo tan innecesario (al menos desde el punto de vista de las máquinas) como lo sería un símbolo decimal.

    Última Nota:  Recuerde que cuando un humano está frente al teclado, él/ella utilizará el símbolo decimal al cual está acostumbrado para proveer los datos a la aplicación .Net.  Es por lo tanto fundamental que el llamado a Decimal.Parse() utilice el símbolo decimal correcto.  Si no utiliza el símbolo decimal correcto, podría aún así pensar que obtuvo un número válido pero que en realidad no es correcto.  Ejemplo:

    Si la aplicación .Net corre en mi sistema, yo digitaría los decimales después de una coma:  83,45.  Si Decimal.Parse() creyera que mi símbolo decimal es el punto y que la coma la utilizo como separador de miles, Decimal.Parse() podría arrojar el valor 8345 o bien 83450!!


    Jose R. MCP
    Tuesday, October 04, 2011 6:41 AM

All replies

  • Eso es un problema de cultura, no de tipo de datos.  La cultura en la cual emiten las facturas utilizan el punto como símbolo decimal.  ¿Cómo recibe las facturas?  ¿Directamente en SQL Server, o las procesa mediante alguna otra forma?
    Jose R. MCP
    Saturday, October 01, 2011 9:52 PM
  • Segun lo que vi en su sistema, coloca el valor de las ventas, con el punto como simbolo decimal, pero toda esta informacion se guarda en la base de datos, para despues imprimirse.
    Saturday, October 01, 2011 11:21 PM
  • Esa no es la información que busco.  ¿Cómo llega a la base de datos la información?  ¿Se importan los datos desde otro SQL Server u otra base de datos, o alguien las digita manualmente, o se importan desde Excel?
    Jose R. MCP
    Saturday, October 01, 2011 11:36 PM
  • Ah no sabria decirte solo vi el sistema en accion, como te comente anteriormente, por eso la duda, el sistema esta echo en visual basic .net y db es en sql server, es lo que me dijeron. Por mi parte quiero hacer lo que vi en ese sistema, los precios se insertan con puntos en una caja de texto en el lenguaje de programacion-visual basic .net, si se apreta una coma igual aparece el punto pero, al pasar los valores a la base de datos por variables parametricas, pues en ahi esta el problema porque siempre se cambia a coma en la base de datos.





    • Edited by RealMaster Sunday, October 02, 2011 3:39 AM
    Sunday, October 02, 2011 12:58 AM
  • Hola. No es claro cual es el problema o qué es lo quieres lograr... ¿La aplicación no funciona? ¿La base de datos no hace el cálculo bien porque los datos llegan en otro formato? Danos más detalles de qué sucede y que necesitas para ayudarte mejor porque como dice José, de pronto es un sistema de interpretación en la aplicación de acuerdo con el idioma o el formato de presentación de datos.

    Gracias y saludos,

     

     


    Guillermo Taylor F.

    IT Pro & Xbox gamer

    My blog

    Sunday, October 02, 2011 1:13 PM
  • ah bueno, perdon por no explicarme mejor

    ¿La aplicación no funciona? R.- La aplicacion que estoy realizando esta hecha en visual basic .net, tengo cajas de texto en donde coloco el valor de la venta de un determinado producto, que se desea comprar, esta validado de tal forma que me acepte solo numeros con punto que representaria al decimal, hasta aqui todo bien, en la base de datos intente con los tipos de datos decimal(18,2), numeric(18,2), pero aqui el problema el valor me sale multiplicado porque mande con punto en las cajas de texto del sistema, si ya no hago la validacion en la caja de texto del sistema y le coloco una coma, me agarra bien el valor pero yo no deseo que los valores del precio de un producto esten separadas por comas decimales sino con el punto, como mencione en el inicio del post.

    ¿La base de datos no hace el cálculo bien porque los datos llegan en otro formato? R.- Si, pues como coloco el valor en el sistema con punto y no con coma me multiplica al valor introducido.

    Gracias por su tiempo

    Sunday, October 02, 2011 4:42 PM
  • Ok, ya entiendo, me parece:

    1. La entrada de datos se hace manualmente desde una aplicación en VB.net que permite únicamente el punto como símbolo decimal.
    2. La aplicación VB.net debe insertar/actualizar datos en SQL Server basado en lo que los usuarios digitan en esta aplicación de VB.net.

    El problema:  SQL Server rechaza los valores numéricos digitados por los usuarios poque SQL Server está usando un sistema numérico en el cual la coma es el símbolo decimal y no el punto.

    Si acerté en lo anterior, le cuento que en mis bases de datos yo utilizo el tipo de datos llamado money para almacenar valores de dinero, que equivale el tipo Decimal en .Net.  Le recomiendo usarlo.

    Segundo:  Es muy malo que una aplicación forze un símbolo decimal particular en el usuario.  La aplicación puede perfectamente utilizar el símbolo decimal del sistema.  La clase CultureInfo (http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx) puede proveerle la información.  CultureInfo.CurrentCulture devuelve un objeto CultureInfo que representa las preferencias del sistema operativo.  Puede entonces obtener un objeto de tipo NumberFormatInfo que tiene la propiedad CurrencyDecimalSeparator que le indica cuál símbolo es el correcto a utilizar como símbolo decimal en números que representan dinero.  Vea http://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencydecimalseparator.aspx para más información y un ejemplo.  Si gusta, puede tal vez usar la propiedad NumberDecimalSeparator para ser más genérico.  Es cosa suya.

    En fin, volviendo al tema, sus cajas de texto deberían utilizar la información del párrafo anterior para solamente permitir ese símbolo.  Si usted hace eso, la conversión a un número es muy simple:

    En C# porque no programo en VB.net:  Decimal miValor = Decimal.Parse(tbElValor.Text);

    El método Parse() aceptará como correcto el símbolo decimal especificado en el sistema operativo, y de ahí la importancia de que la validación del texto en la caja de texto utilice el valor configurado en el sistema operativo.

    Y ese sería el ideal aquí.  Pero bueno, los métodos Parse() y TryParse() también aceptan un objeto cultura para realizar las interpretaciones.  Si es demasiado importante para usted mantener el uso del punto como símbolo decimal, puede pasar un objeto de cultura (¿o es un NumberFormatInfo? En fin, uno de esos) que sí utilice el punto como símbolo decimal para así obtener el valor.

    Pero todo lo anterior es útil ÚNICAMENTE si no construye el SQL en una cadena de texto.  Esto es muy mala práctica de todas formas.  Lo mejor es hacer las cosas via Stored Procedures.  Los Stored Procedures tienen parámetros con sus tipos fuertemente especificados.  Ejemplo:

    Create Procedure dbo.sp_InsertarNuevoItem
        @Nombre nvarchar(50)
        , @Valor money
    As
    Begin
        Set NoCount On;
        Insert Into dbo.tblMisItems (Nombre, Valor)
        Values (@Nombre, @Valor);
    
        Return @@Error;
    End
    Go
    

    Cuando usted utiliza SP's, los tipos de datos son validados y así no tiene problemas de puntos o comas.  Un valor Decimal en .Net pasará sin conversión alguna necesaria al SP como valor del parámetro @Valor.


    Jose R. MCP
    Sunday, October 02, 2011 8:01 PM
  • Gracias por la respuesta Jose, lo hice por el lado del procedimiento almacenado y con el tipo de dato money, pero sigue habiendo el problema del guardado en la tabla con el punto decimal, me filtra en el procedimiento almacenado si le coloco con punto y coloca en la tabla la coma, pero si coloco coma el procedimiento almacenado le sale error 8144.

    Ejmplo: 128,0000 (ciento veintiocho pesos), 128,5000 (ciento veintiocho pesos con cincuenta centavos)

    El resultado me da como en el ejemplo, hay alguna manera que en la base de datos se refleje el guardado de esta manera:

    Ejmplo: 128.00 (ciento veintiocho pesos), 128.50 (ciento veintiocho pesos con cincuenta centavos)

    Monday, October 03, 2011 4:39 AM
  • Le repito nuevamente que el uso de un punto o una coma es una mera cuestión de presentación según la cultura.  Internamente, un número de punto flotante es idéntico sin importar la cultura.  Usted debe utilizar Decimal.Parse() para obtener el número en el formato adecuado.  Como no programo en VB.net, le muestro un ejemplo en C#:

    void InsertarNuevoItem(string nombre, decimal valor)
    {
        using (SqlConnection conn = new SqlConnection(<el conn. string aquí>))
        {
            conn.Open();
            using (SqlCommand cmd = new SqlCommand("sp_InsertarNuevoItem", conn))
            {
                cmd.CommandType = StoredProcedure;
                cmd.Parameters.AddWithValue("Nombre", nombre);
                cmd.Parameterse.AddWithValue("Valor", valor);
                cmd.ExecuteNonQuery();
            }
        }
    }
    
    //Ahora imaginemos que el guardado de los datos se da debido al clic de un botón:
    protected void btnGuardar_Click(object sender, EventArgs e)
    {
        string nombre = tbNombre.Text;
        try
        {
            //Como verá, la siguiente línea es la clave.  Si ejecuta sin error
            //entonces la variable valor contiene un número válido, ya sea
            //entero o con decimal, según lo haya digitado el usuario.
            //Pasada esta línea, el símbolo decimal utilizado deja de tener
            //importancia.
            decimal valor = Decimal.Parse(tbValor.Text);
            InsertarNuevoItem(nombre, valor);
        }
        catch (System.Exception ex)
        {
            tbError.Text = "No puede interpretarse el valor digitado como un valor válido numérico.";
            //Haga lo que quiera con la excepción, incluyendo escribirla a un log.
        }
    }
    

    Lo anterior DEBE trabajar correctamente.  No veo cómo podría fallar.  Si falla de alguna forma, le agradeceré que sea 100% explícito en el error que se muestra y en la línea de código en que falla.  Sé leer VB.net, pero no lo escribo.  Confío en que podrá traducir mi ejemplo a VB.net.


    Jose R. MCP
    Monday, October 03, 2011 5:25 AM
  • se va por el false del if, no puedo adicionar y el error no lo puedo ver pero parece que no ejecuta bien en funcion de ExecuteNonQuery, por eso se va por el false.

    'codigo del boton:

    Dim

    monto As Decimal = Decimal.Parse(TextBox1.Text)

    comando = New SqlCommand
     
    comando.Connection = objconexion

    comando.CommandText ="sp_InsertarNuevoItem" 

    comando.CommandType = CommandType.StoredProcedure

    comando.Parameters.Add("@valor", SqlDbType.Money).Value = monto
     
    objconexion.Open()
     
    If comando.ExecuteNonQuery() > 0 Then 
    MessageBox.Show("Datos adicionados...")
     Else 
    MessageBox.Show("Hubo problemas en la adicion...")
     End If 
    objconexion.Close()

    'procedimiento almacenado:

    ALTER Procedure [dbo]. [sp_InsertarNuevoItem]
    @valor money

    As

    Begin

    Set NoCount On;
    Insert Into ventas (venta )
    Values (@valor);
    Return @@Error ;
    End


    Gracias de antemano

    en la parte que comentas  Internamente, un número de punto flotante es idéntico sin importar la cultura quiere decir que si mando el numero decimal con punto decimal desde el lenguaje de programacion ya sea visual basic .net o C# en la tabla de base de datos se insertara con coma decimal, si es asi, necesito para mis resportes que se llame desde la base de datos con punto decimal pues sera lo que imprimire.
    • Edited by RealMaster Tuesday, October 04, 2011 2:05 AM
    Tuesday, October 04, 2011 1:57 AM
  • El método ExecuteNonQuery() devuelve el total de registros afectados.  Sin embargo, el procedimiento sp_InsertarNuevoItem tiene NoCount en On, lo que quiere decir que no devolverá la cantidad de registros afectados.  Por lo tanto, su procedimiento para enterarse si funcionó o no lo está engañando.  Si revisa la base de datos, probablemente verá que los registros están de hecho siendo actualizados.

    Para revisar en .Net si el procedimiento en SQL Server ejecutó correctamente, debe obtener el resultado devuelto por el procedimiento.  En C#:

    comando.Parameters.Add(new SqlParameter("ret", SqlDbType.Int)).Direction = Direction.ReturnValue;
    
    ...
    comando.ExecuteNonQuery();
    if ((int)comando.Parameters["ret"].Value == 0)
    {
        //El resultado es igual a cero, lo que quiere decir que fue exitoso.
    }
    else
    {
        //El resultado fue distinto a cero, lo que indica que hubo un error.
    }
    



    Jose R. MCP
    Tuesday, October 04, 2011 2:06 AM
  • Ah bueno no me fije en esa parte, bueno ahora corre bien, pero existe un problema:

    Cuando coloco 200.80 en la base de datos lo guarda asi --> 20080,0000

    Si coloco 200,80 en la base de datos me lo guarda asi --> 200,80

    todo esto desde el lenguaje de programacion.

    y me pondrias responder esta duda:

    en la parte que comentas  Internamente, un número de punto flotante es idéntico sin importar la cultura quiere decir que si mando el numero decimal con punto decimal desde el lenguaje de programacion ya sea visual basic .net o C# en la tabla de base de datos se insertara con coma decimal, si es asi, necesito para mis resportes que se llame desde la base de datos con punto decimal pues sera lo que imprimire.


    • Edited by RealMaster Tuesday, October 04, 2011 2:40 AM
    Tuesday, October 04, 2011 2:31 AM
  • Pues me cuesta explicarle un tanto sin referirme a punteros y examinar la memoria RAM directamente (idealmente en C++).  Pero bueno, voy a tratar:

    Un número de punto flotante de tipo float, por ejemplo, es un número que se almacena en 4 bytes.  Esos 4 bytes tratan de representar lo mejor posible el número solicitado (porque a veces no es posible) según los estándares de punto flotante de la IEEE.  Ese número, o sea, esos 4 bytes de memoria, tienen apariencia idéntica en cualquier PC en el mundo, sin importar el idioma en que la PC esté configurada, siempre y cuando la arquitectura de hardware sea la misma (big endian, little endian).

    Ahora lo invito a que relea el párrafo anterior.  Cuénteme:  ¿Encontró usted alguna referencia al símbolo decimal?  La respuesta es No, esos 4 bytes no contienen el símbolo decimal en ninguna parte.  Pues es igual con el tipo de datos double y con el tipo de datos decimal.  Una variable de tipo float representa 4 bytes que representan un número; una variable de tipo double son 8 bytes que representan un número; una variable de tipo decimal son 10 bytes (creo) que representan un número que siempre tiene 4 dígitos decimales (¡¡pero nada de símbolos decimales!!).

    Así que ¿cuándo entra en juego el símbolo decimal?  Cuando el humano quiere LEER el contenido de las variables numéricas en un formato que el humano entiende.  El humano no está acostumbrado a ver la constante de Avogadro cuyo valor es 6,022045e23 (sí, yo uso la coma como símbolo decimal) como una secuencia de 32 números de 1's y 0's, que es el lenguaje de la PC.

    Así que el símbolo decimal únicamente se usa para COMPLACER la vista y el ojo del humano, pero internamente no tiene relevancia alguna en la representación INTERNA en lenguaje de máquina (ceros y unos).  Las máquinas son capaces de almacenar y manipular números de punto flotante sin tener que recurrir nunca a una definición de un separador decimal.  Simplemente no lo ocupan.

    Eso quiere decir que si usted ve un número en su SQL Server con coma porque el servidor está ajustado a utilizar comas como símbolo decimal, eso NO quiere decir que una aplicación .Net en otra PC esté obligada a ENTENDER O DESPLEGAR el valor utilizando la misma convención de símbolo decimal.  ¿Por qué?  Porque SQL Server es capaz de transferir el valor del número de punto flotante en lenguaje de máquina, y el lenguaje de máquina no especifica símbolo decimal alguno, nuevamente, porque no lo necesita.

    ¿Me he explicado mejor?

    Asumiendo que ya me entiende, el símbolo decimal es una mera cuestión COSMÉTICA.  Si usted tiene una variable decimal con un valor, ese valor es correcto en la PC que lo contiene y en el SQL Server en el que se almacena, aún cuando ambas PC's utilicen símbolos decimales distintos.  Esto es posible porque la aplicación .Net transmitirá el valor en lenguaje de máquina que no admite la definición de algo tan innecesario (al menos desde el punto de vista de las máquinas) como lo sería un símbolo decimal.

    Última Nota:  Recuerde que cuando un humano está frente al teclado, él/ella utilizará el símbolo decimal al cual está acostumbrado para proveer los datos a la aplicación .Net.  Es por lo tanto fundamental que el llamado a Decimal.Parse() utilice el símbolo decimal correcto.  Si no utiliza el símbolo decimal correcto, podría aún así pensar que obtuvo un número válido pero que en realidad no es correcto.  Ejemplo:

    Si la aplicación .Net corre en mi sistema, yo digitaría los decimales después de una coma:  83,45.  Si Decimal.Parse() creyera que mi símbolo decimal es el punto y que la coma la utilizo como separador de miles, Decimal.Parse() podría arrojar el valor 8345 o bien 83450!!


    Jose R. MCP
    Tuesday, October 04, 2011 6:41 AM