十进制值1,5在DB中最终为15 - 为什么?

时间:2011-07-27 13:27:20

标签: c# ado.net decimal

向互联网上的优秀人士致意:)

我有一个字符串值“1,5”,在调试器中查看它时,Convert.ToDecimal()结束后为1.5M。到目前为止我觉得这么好。然后,十进制值将传递给数据集内的存储过程调用。我感兴趣的参数类型在DB中定义为NUMBER(7,2),因此它应该允许在小数分隔符后面有数字的数字。

问题是,沿着该行的某个位置,十进制值会丢失其分隔符,并将精度与缩放结合起来构成全新的数字,如本文标题中所示。我甚至尝试在该存储过程调用中的参数集合中设置Precision和Scale以匹配DB(7,2),但它也没有帮助。

你知道这里会发生什么吗?

编辑:

以下是调用存储过程的代码:

CaseFactory.UtilsAdapter.SetCaseAction(DefId, action, doneBy, assignedTo, comment, status, searchStatus, priority, access, relStatus, relStatusFixKit, totalhrs, out Common.RETURN_CODE, out Common.RETURN_TEXT);

=> SetCaseAction只是使用DataSet机制在DB中调用存储过程。 'totalhrs'是我感兴趣的参数,此时是小数1.5M。我还检查了Oracle中的NLS_NUMERIC_CHARACTERS并将它们设置为','

所以它使用逗号表示小数,空格表示数千。没有什么不寻常的我能看到那里。唯一奇怪的是,'1,5'最终为'1.5M',在ToDecimal()之后有一个点,可能会被错误地解释。但是,似乎不太可能,因为我的服务器上的区域设置也使用','作为小数分隔符,除非.NET使用一些不同的设置?真的很困惑。

5 个答案:

答案 0 :(得分:4)

我怀疑你是在没有正确文化的情况下在某些时候转换它,例如通过ToString()将它连接到TSQL查询(而不是使用参数),或者在调用{{1}时只使用错误的文化}}。 “1小数点5”和“1组分隔符5”之间“1,5”不明确;后一种情况被解析为15。

答案 1 :(得分:2)

我认为这是一个本地化问题 - 逗号用于分隔数千个,而不是在许多系统中指示小数位。查看数据库中的语言设置。

答案 2 :(得分:1)

SQL中的小数点分隔符为.,而不是,。因此 1,5 被解释为 15 ,而不是 1.5 。要避免此类问题,请始终使用参数化查询,而不是将值直接编码到查询文本中。

答案 3 :(得分:1)

有关如何将值传递给存储过程的一些代码将是有用的(如果您自己这样做)。

有些人仍然使用String.Format来生成查询字符串。除了导致您所描述的错误之外,这对SQL注入也是开放的。

您应该使用参数化查询。通常,做这样的事情会起作用:

SqlCommand cmd = new SqlCommand("...", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@myDecimal", decimalVariable);

修改
当然,这不应仅仅针对某些参数进行,而是针对存储过程的所有参数进行!以上只是一个关于如何将参数传递给存储过程的示例。

答案 4 :(得分:-1)

正如托马斯所说,在SQL中,SQL中的小数分隔符是“。”

在这种情况下,你可以使用:

yourVariable.Replace(',','。')

然后,将参数传递给执行事务的函数。