从.NET sqlcommand传递给SQL的值不正确

时间:2013-04-25 13:28:07

标签: .net sql-server vb.net stored-procedures sql-server-2008-r2

为什么当我运行下面的代码时,它应该在表中插入值122387593.6,它是否插入值122387593.59999999?

我已跟踪.net发出的调用,可以看到该值是以122387593.59999999传递给SQL的,但调试参数值时返回为122387593.6?!

我无法理解为什么.NET会这样做 - 非常感谢任何帮助。

   ---SQL Code

   CREATE TABLE [dbo].[tblNum](
[Num] [numeric](28, 8) NOT NULL
   ) ON [PRIMARY]


   CREATE PROCEDURE spNumInsert (@Num numeric(28,8))
   AS
   BEGIN
   INSERT INTO tblNum VALUES(@Num)
   END
   GO

   --.NET Code

    Dim a = Double.Parse("122387593.6", Globalization.CultureInfo.InvariantCulture)

    Dim con As SqlConnection = New SqlConnection("Server=server;Database=database;Trusted_Connection=True;")
    Dim com As SqlCommand = New SqlCommand("spNumInsert", con)
    com.CommandType = CommandType.StoredProcedure
    com.Parameters.Add(New SqlParameter("@Num", a))

    con.Open()
    com.ExecuteNonQuery()
    con.Close()
    con.Dispose()

4 个答案:

答案 0 :(得分:10)

double表示IEEE754。 IEEE754 无法表达每个值。 IEEE754中很可能122387593.6 不存在122387593.59999999是最接近的近似值。

如果你需要与我们肉食人类倾向于同意的价值相匹配的“精确”近似值(注意术语中的矛盾),那么你应该使用decimal,而不是double

要明确:decimaldouble都被迫近似 - 只有这么多你才能将这样一系列可能的值拟合成有限字节。但它们近似的方式是不同的。 decimal适用于金钱等离散测量; double适用于连续测量。

答案 1 :(得分:3)

请勿使用Double.Parse。您需要使用Decimal

您的对象a已经是122387593.59999999,因为这是122387593.6必须在浮点标准中表示的,这是双倍的。

答案 2 :(得分:1)

问题在于.NET的精度为double。如果您在此行之后结帐变量a

Dim a = Double.Parse("122387593.6", Globalization.CultureInfo.InvariantCulture)

你会注意到它已经错了。您可以尝试使用decimal更精确。

答案 3 :(得分:-3)

使用功能

  ROUND ( numeric_expression , length [ ,function ]  )