数据库的商品表(goods)有个字段为价格(price),类型为smallmoney,实际上用到的仅像是12.3这类的小数点后留一位的数字,也就是1.1~999.9的范围,不知道类型定为smallmoney对不对,因为我发现小数点后总是有4位,像是13.0000。而我希望从数据库显示到界面上该为小数点后一位才对,这就是我的困扰,不知道应该是当初插入表/更新表(insert into/update)的时候格式化,还是从数据库显示出来的时候再格式化?再或者是字段类型取的不对?不知道说的明白否?希望大家给出最简单最易行的办法,并且有例子,小女谢过了。解决后高分!
过几天要答辩,急了阿!

解决方案 »

  1.   

    smallmoney数据类型的小数点后精确到四位.
    其实你把数据类型定义为decimal 或 numeric,不就结了?
      

  2.   

    妹妹,有几个问题你应该搞明白:
    1、价格、金额本来就应该使用SmallMoney,这种类型专门设计来给价格金额这种列使用的。
       所以你使用SmallMoney没错
    2、现在你的可能只要小数点后一位,以后呢?价格要精确呢?
       所以为了可扩展性,你应该保留这种数据类型
    3、你应该是为了显示的时候只取得一位小数,如果用户需要那他可以输入4位小数,不需要,只输入一位就OK了。
       所以现在的问题时,怎么显示一位小数呢?而且要考虑输入的不是一位小数时的4舍5入问题。
    4、如何实现显示时的舍入和显示问题?
       你可以使用以下语句了解一下各种方法的区别:
    declare @m as smallmoney
    set @m=.0941
    select round(@m,1) as myCol1,LEFT(cast(round(@m,1) as varchar),LEN(cast(round(@m,1) as varchar))-1) as myCol2
    set @m=21.0951
    select round(@m,1) as myCol1,LEFT(cast(round(@m,1) as varchar),LEN(cast(round(@m,1) as varchar))-1) as myCol2
       或者你可以在程序中用FORMAT函数对显示进行格式化。
       不过,那样会很不爽,因为你可能只需要LIST结果集。所以用FORMAT函数来对大量结果集进行格式化会是低效率的。
       另外:假如你要用FlexGrid对结果集进行VIEW,那么,用以上的SQL语句有一个缺点:FlexGrid的对齐方式会按文本方式对齐,也就是左对齐,而数据一般是右对齐。因此,你可能需要对ColAlignment进行设置。以上报告。
      

  3.   

    Dim p As String = TextBox1.Text   '输入的价格     (如:12.1万元)
            Dim v1 As String = ""
            Dim v2 As String = ""
            Dim v3 As String = ""        Dim connectstr As String
            connectstr = "Data Source=.;user id=sa;initial catalog=auction"
            Dim myconnect As New SqlConnection(connectstr)
            
            Dim sqlstr1 As String  '更新goods表的最新拍卖价格
            sqlstr1 = "update goods set price='" & p & "'"   
            Dim mycommand As New SqlCommand(sqlstr1, myconnect)
            Dim dr As SqlDataReader
            myconnect.Open()
            dr = command.ExecuteReader(System.Data.CommandBehavior.CloseConnection)
            If dr.Read() Then
                
                v1 = dr("price")  'goods表中的当前价格赋给变量v1    '(如:12万元)
                FormatNumber(v1, "0.0")
                
                v2 = dr("range")  'goods表中的加价幅度赋给变量v2    '(如:1000元)
                FormatNumber(v2, "0.0")
           
            End If
            dr.Close()
            myconnect.Open()
                
                    '拍卖价格一定是加价幅度的整数倍且要大于当前价格
                    If p > v1 And (p - v1) * 10000 Mod v2 = 0 Then   '(如:(12.1万-12万元)*10000 Mod 1000=0)
                        p = v1 + v2 / 10000        '(如:12万+1000元/10000=12.1万元)
                        mycommand.ExecuteNonQuery()
                        TextBox1.Text = ""
                        msg.Text = "拍卖成功!"
                    Else
                        msg.Text = "请输入正确的价格"
                    End If
            myconnect.Close()
    现在的问题是我输入了12.1后点提交,总是显示"请输入正确的价格",我哪里错了?和格式化字符串有关系么?
      

  4.   

    楼上:
    1、价格、金额本来就应该使用SmallMoney,这种类型专门设计来给价格金额这种列使用的。
       所以你使用SmallMoney没错
    ______________________________________________
    不好意思,这儿与你的看法有所不同.看看用友、金算盘这些财务软件(二者都是VB写的)在价格、金额字段中有哪个软件是用SmallMoney或者Money型的?它们在VB中用的是DOUBLE型,在SQL中用的是FLOAT型,也因为如此,对于这样一些进销存软件来说一个常见的问题是库存尾数问题(库存为零,但金额还有小数在)。
    正因为以上原因,我认为对于小数运算用decimal是较好的选择。正如楼上所说SmallMoney只能到小数后4位,那你如果精确到7位、8位的话又该怎样解决呢?哪种数据类型适用我就用哪个,凭什么说“价格、金额本来就应该使用SmallMoney”呢?
      

  5.   

    妹妹:
    一般情况下,货币就是应该用 money 和 smallmoney 表示。money 对应 VB 中的 Currency。 
    money 和 smallmoney 是定点数,它存储的实际上是整数格式。表达时除以 10000。这样左右一个好处:
    我们知道,十进制的小数并不都是可以用二进制小数精确表示的。所以浮点数做加减法时,其十进制结果往往有误差。当然,如果误差足够小,而你又能对结果进行适当的取舍,就不会有问题。但这总是比较麻烦的吧?有些财务软件的最初产生年代比较早,它使用了比较传统的数据格式,可以理解。那我们现在有好用的东西为什么不用呢?数据库保存的往往是计算的结果,按照国际金融惯例,保留到本币的万分之一就足够精确了。何况妹妹只需要 1 位小数?如果你需要保留一个更高精度的数据,完全可以使用其它数据格式,甚至自定义格式,麻烦一点罢了。就说 Decimal 类型,12字节长,在 VB 中要定义成 Variant。这就好比削皮刀是专门为削果皮设计的,你非要用菜刀,说,没准儿我得拍果泥、剁果块。那由你了。最后,妹妹需要明白存储格式和显示格式的区别。数据在内存或磁盘上存储时,并非我们看到的格式,它是由某种特殊规定的。money 和 smallmoney 约定了精确到小数点后 4 位的。所以,你即使存入的是整数,它也有 4 位小数(全为 0 而已)。你需要在显示时进行格式化。
      

  6.   

    谢谢各位大哥,帮我看看上面我写的那段程序,为啥有问题啊?我以为是因为格式化字符串的问题,可是好像我格了也没有得解决,不知是格的不对?还是判断语句的问题?它总是跳到else哪里真郁闷
      

  7.   

    我刚才修改了一下程序:
    首先我在数据库中把price字段类型改为decimal,并把精度改为1,这样小数点后就保留一位了,自然显示的时候也就是12.0那样的了,无须再格式化。
    其次我把v1,v2,p都转换为double型了
            Dim p As Double = Val(TextBox1.Text)
            Dim v1 As Double
            Dim v2 As Double
            .
            .
            .
           If dr.Read() Then
                v1 = Val(dr("price"))
                v2 = Val(dr("range"))       End If但在后面的判断上还是直接跳到else,到底怎么回事?真晕了~        If p > v1 And (p - v1) * 10000 Mod v2 = 0 Then   '(如:(12.1万-12万元)*10000 Mod 1000=0)
           p = v1 + v2 / 10000        '(如:12万+1000元/10000=12.1万元)
           mycommand.ExecuteNonQuery()
           TextBox1.Text = ""
           msg.Text = "拍卖成功!"
           Else
           msg.Text = "请输入正确的价格"
           End If
      

  8.   

    补充一下:我又做了一个测试:我把加价幅度变为3000元时,底价为12万元,当输入13时输出错误信息“请输入正确的价格”(13-12)*10000不是3000的整数倍,说明程序还是运行了(p - v1) * 10000 Mod v2 = 0这个判断语句。但为什么输入12.3时也输出错误信息“请输入正确的价格”??!!
      

  9.   

    Dim p As Currency = Val(TextBox1.Text)
            Dim v1 As Currency
            Dim v2 As Currency