字符串“0.080”加倍为80.00 [重复]

Posted

技术标签:

【中文标题】字符串“0.080”加倍为80.00 [重复]【英文标题】:String "0.080" to double makes 80.00 [duplicate] 【发布时间】:2013-03-12 08:59:27 【问题描述】:

我在c#中有这个问题,我想将一个字符串转换为double。

textBoxKostOnderhoud.Text = "0.08";

kost.OnderhoudKost = double.Parse(textBoxKostOnderhoud.Text);

这会在我的数据库中生成 80.00,我不知道为什么。这个问题有解决办法吗?

这就是我将值添加到数据库 (mysql) 的方式

public bool insert(Kost kost)

    string query = "INSERT INTO kost (wagenId, onderhoudKost, tolKost, bedrijfsVerzekering, autoVerzekering, ladingVerzekering, wegenBelasting, eurovignet, accountantKost, telefoonKost, documentenEnVergunningen, onvoorzien, overige, andere) VALUES('" + kost.WagenId + "', '" + kost.OnderhoudKost + "', '" + kost.TolKost + "', '" + kost.BedrijfsVerzekering + "', '" + kost.AutoVerzekering + "', '" + kost.LadingVerzekering + "', '" + kost.WegenBelasting + "', '" + kost.Eurovignet + "', '" + kost.AccountantKost + "', '" + kost.TelefoonKost + "', '" + kost.DocumentenEnVergunningen + "', '" + kost.Onvoorzien + "', '" + kost.Overige + "', '" + kost.Andere + "')";

    if (this.OpenConnection())
    
        //Create Command
        MySqlCommand cmd = new MySqlCommand(query, connection);
        //Create a data reader and Execute the command
        cmd.ExecuteReader();

        //close Connection
        this.CloseConnection();

        return true;
    
    else
    
        return false;
    

sql

CREATE TABLE IF NOT EXISTS `kost` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `wagenId` int(11) NOT NULL,
  `onderhoudKost` double(10,2) NOT NULL,
  `tolKost` double(10,2) NOT NULL,
  `bedrijfsVerzekering` double(10,2) NOT NULL,
  `autoVerzekering` double(10,2) NOT NULL,
  `ladingVerzekering` double(10,2) NOT NULL,
  `wegenBelasting` double(10,2) NOT NULL,
  `eurovignet` double(10,2) NOT NULL,
  `accountantKost` double(10,2) NOT NULL,
  `telefoonKost` double(10,2) NOT NULL,
  `documentenEnVergunningen` double(10,2) NOT NULL,
  `onvoorzien` double(10,2) NOT NULL,
  `overige` double(10,2) NOT NULL,
  `andere` double(10,2) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `wagenId` (`wagenId`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=64 ;

【问题讨论】:

请提供重现观察到的行为的完整代码示例。你如何验证值是80.00 如果你有“0,080”怎么办?这可能是文化问题,但我不确定,因为您没有提供太多信息。 "0,080" 产生另一个值,我想? 如果你使用 Convert.ToDouble 方法呢?编辑:没关系,不起作用。 我在我的 MYSQL 数据库中使用双精度,如果我尝试 0,080,我将在数据库中得到 0.000。 【参考方案1】:

我怀疑您使用的文化是小数点分隔符是“,”,分组分隔符是“.”。

您可以指定解析时使用的文化:

double d = double.Parse(s, CultureInfo.InvariantCulture);

这是否合适取决于上下文,通常 - 字符串来自哪里?如果是用户,你知道他们的文化是什么吗?如果它不是来自用户,数据源本身是文本的,还是有一种方法可以在不进行任何字符串转换的情况下获取值?

请注意,如果这是针对 currency 值,您几乎可以肯定使用 decimal 而不是 double

编辑:现在您已经包含了 SQL,我们可以看到为什么值没有正确传播到数据库:

// Note properly broken, but this is all on one line. (Ick to start with.)
string query = "INSERT INTO kost (wagenId, onderhoudKost, tolKost, 
   bedrijfsVerzekering, autoVerzekering, ladingVerzekering, wegenBelasting, 
   eurovignet, accountantKost, telefoonKost, documentenEnVergunningen, onvoorzien, 
   overige, andere) VALUES('" + kost.WagenId + "', '" + kost.OnderhoudKost + "', '" 
   + kost.TolKost + "', '" + kost.BedrijfsVerzekering + "', '" +
   kost.AutoVerzekering + "', '" + kost.LadingVerzekering + "', '" + 
   kost.WegenBelasting + "', '" + kost.Eurovignet + "', '" + kost.AccountantKost + 
   "', '" + kost.TelefoonKost + "', '" + kost.DocumentenEnVergunningen + "', '" + 
   kost.Onvoorzien + "', '" + kost.Overige + "', '" + kost.Andere + "')";

您正在将所有值转换为 SQL 中的字符串,并希望您的数据库能够以同样的方式再次解析它们。碰巧的是,由于您的默认文化,它不会再次出现。

更重要的是,这里有一个大量SQL injection 攻击漏洞。

不要这样做。请改用参数化 SQL,在 SQL 中放置 占位符,然后单独指定参数值。好处:

防止 SQL 注入攻击 通过将代码(SQL)与数据分离,让您的 SQL 语句更加更简洁 减少您最终完成的转化次数,因此您不必担心文化等问题

请参阅您正在使用的 MySQL 驱动程序的文档,了解用于参数的确切格式(我相信根据驱动程序的不同,格式可能会略有不同) - 但从根本上说,这适用于 all 您的数据库访问权限,无论您正在与之交谈的任何数据库以及您使用的任何语言。

【讨论】:

..我在发布 1 秒后看到了一个赞成票。 这在我调试代码时有效。变量有 0.08。但是当我检查我的数据库时,它仍然有 8.00 @Mankeeey:也许下一个问题是您如何将值存储在数据库中?我们不知道您的代码是什么样的。 (如果您没有使用参数化 SQL,这很可能是问题所在。) 现在将代码包含在我的问题中。 @Mankeeey:对。和我想的一样。 不要那样做。将编辑我的答案。【参考方案2】:

您可以在double.Parse 中使用CultureInfo.InvariantCulture 来忽略当前文化:

double d = double.Parse(s, CultureInfo.InvariantCulture);

Demo

output:
0.08

【讨论】:

【参考方案3】:

由于您要连接字符串以创建 SQL 命令文本,因此您的 double d 可能会转换为字符串“0,080”,MySql 可能会将其解释为 80。

【讨论】:

好点。我至少会尝试在 SQL 字符串中去掉这个参数的引号。参数化的 SQL 会更好。向我们展示数据库中该字段的字段定义可能会有所帮助。

以上是关于字符串“0.080”加倍为80.00 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

替换有时加倍的字符的单个实例

为什么我擦除其他字符时最后一个字符加倍,并且如何防止呢?

将字符串转换为双精度的最佳方法

如何将 sql datetime2 转换为加倍?

TryCast 加倍?

Objective c int 加倍计算[重复]