【问题标题】:Formatting Decimal Values from SQL Server Database格式化 SQL Server 数据库中的十进制值
【发布时间】:2011-10-14 12:03:13
【问题描述】:

我正在使用现有的 SQL Server 数据库,表列定义为decimal(4,2)。但是,我被要求防止代码舍入小数位。

所以我尝试将列类型更改为decimal,它会自动转换为decimal(18, 0),这会立即清除我现有值的任何小数部分。 (很好。默认的十进制类型是整数。有什么意义?)

所以我尝试将列类型更改为decimal(8,5)。由于小数点后 5 位超出了需要,因此消除了舍入问题。

但是,每当我在 C# ASP.NET 应用程序中打印此值时,它总是被格式化为小数点后 5 位(例如12.34000)。我不明白这一点。当我从数据库中读取值时,我将它分配给一个常规的decimal 值。那么decimal 值如何“知道”小数点后应该有 5 位呢?

更重要的是,如何在没有尾随零的情况下显示此值?我猜有一种方法可以格式化值。但是,由于它在许多地方都使用过,所以如果它不自动附加尾随零会更好。如果需要,我可以更改数据库中的数据类型。

【问题讨论】:

    标签: c# sql-server decimal


    【解决方案1】:

    十进制总是以尾随零返回。这是按照惯例 - 尾随零表示有效数字的数量。

    在您的情况下,小数 (8, 5) 表示该数字共有 8 位,其中 5 位在小数点后。

    试试这个Select CAST (1 as decimal (8, 5))会返回1.00000

    因为这意味着小数点前只有 3 位,所以下面的语句 Select CAST (1000 as decimal (8, 5)) 会给你一个错误 Arithmetic overflow error converting int to data type numeric.

    【讨论】:

    • 那么为什么你的第一个例子不返回00000001.00000。这难道不是同样的意义吗?我只是在这里使用了错误的数据类型吗?
    • @Jonathan Wood - 有效数字的约定是在小数点之后,而不是之前。
    • 好的,那么返回001.00000 与现在所做的一样有意义吗?
    【解决方案2】:

    在控制台应用中试试这个小 sn-p:

    decimal d1 = 12.34M, d2 = 12.3400M;
    
    Console.WriteLine("{0} {1}", d1, d2);
    Console.WriteLine("{0:0.0###} {1:0.0###}", d1, d2);
    

    是否、如何以及在何处应用格式取决于您。

    【讨论】:

    • 如果我将鼠标悬停在调试器中的十进制值上,它会显示“12.34”。如果这对 Visual Studio 来说已经足够好了,为什么没有更直接的方式来格式化这种方式呢?在程序中的任何地方都找到显示列并实现格式化字符串是有问题的。我是否使用了错误的数据类型?
    • 关于数据类型:Float 或 Real 将解决您的尾随零,但请查看它们在舍入方面的作用。它们是近似类型。
    • 数据实际上代表一个税率。所以它可能是 6.625 或 14.25。似乎小数一开始就有点过分了,即使除了格式问题。
    【解决方案3】:

    您应该真正考虑在表示层而不是数据层中格式化您的货币。 通常,您希望将货币值存储在小数 (10,18) 字段中。您可以检索十进制值并将其格式化以在 csharp 中显示,例如 str = String.Format("{0:C}", myDecimalValue);

    【讨论】:

    • 当然。这就是为什么我的表示层想要根据内部表示对其进行格式化如此令人沮丧的原因。所以这意味着我需要在几十个地方添加格式化代码。也许我使用了错误的数据类型。 C 是货币的格式。这不是货币。
    【解决方案4】:

    我将数据库列更改为float,并将C#变量类型设置为double

    问题解决了。

    【讨论】:

      【解决方案5】:

      Entity Framework 默认使用十进制(18,2)。如果你不告诉它,它的格式将不适合 SQL Server 数据类型。

      要告诉 EF 应该为每个属性使用什么 SQL 数据类型:

      public class DbEntities : DbContext {
          protected override void OnModelCreating(DbModelBuilder modelBuilder) {
              modelBuilder.Entity<Location>().Property(location => location.Latitude).HasPrecision(9, 6);
          }
      }
      

      还有其他方法可以对所有属性执行此操作:Decimal precision and scale in EF Code First

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-29
        • 1970-01-01
        • 2011-09-24
        • 2013-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多