逗号vs点作为小数分隔符

时间:2015-01-22 08:35:50

标签: c# sqlite

我有一个C#应用程序将一些数据写入SQLite数据库,当我尝试将C#double存储到SQLite REAL字段时会出现问题。

它使用逗号作为小数分隔符将其保存到数据库中(在我的国家/地区通常情况下,不确定它是否适用于任何内容)。

该表具有以下结构:

CREATE TABLE `valoresStock` (
  `Fecha`   TEXT,
  `IdArticulo`  TEXT,
  `IdColor` INTEGER,
  `KgPorUnidad` REAL,
  `Stock`   REAL,
  `CostePorKg`  REAL,
  `CostePorUnidad`  REAL,
  PRIMARY KEY(Fecha,IdArticulo,IdColor)
);

我在我的应用中使用的查询如下:

cmd.CommandText = "INSERT INTO valoresStock (Fecha, IdArticulo, IdColor, KgPorUnidad, Stock, CostePorKg, costePorUnidad) VALUES ('" + DateTime.Today + "','" + referencia.idArticulo + "', '" + referencia.idColor + "', '" + referencia.kilos + "', '" + referencia.stockActual + "', '" + referencia.valorPorKg + "', '" + referencia.valorPorUnidad + "') ";

正如我所说,最后四个字段是类型为double 。没有错误。

然后数据存储如下:

data structure

也就是说,当它没有小数部分时使用点,而当它没有时使用逗号。

这个问题是例如我使用SELECT语句来计算时,例如:

SELECT VS.Fecha, VS.IdArticulo, VS.IdColor, (VS.Stock * (VS.CostePorUnidad + VS.CostePorKg * Vs.KgPorUnidad)) AS Valor FROM valoresStock VS

这给出了以下结果,这是错误的(只用带点的数字)。

error with commas

所以,如果我在表格中手动更改点的逗号,它就能正常工作。

all with dots

但是如何让我的应用做到这一点,某种文化改变?

或者我可以让SQLite理解或自动转换逗号吗?

为什么SQLite接受该号码是否有效,如果它以后不理解?

3 个答案:

答案 0 :(得分:6)

您应该使用参数化查询来插入值。这意味着您只应在SQL字符串中使用参数占位符,并将实际值添加为查询参数。

这通常是防止SQL注入攻击的好习惯。虽然这些可能是一个较小的问题,如果你的所有值都是数值(甚至可能不直接来自用户输入),这个参数化也可以确保参数值的格式就像目标引擎想要/需要它们一样。无需担心正确的小数点分隔符即可识别浮点数,并且无需担心正确的引号和转义即可识别字符串。

因此,您的INSERT语句应更改如下:

cmd.CommandText = "INSERT INTO valoresStock (Fecha, IdArticulo, IdColor, KgPorUnidad, Stock, CostePorKg, costePorUnidad)"
    + "VALUES (@fecha, @idArticulo, @idColor, @kgPorUnidad, @stock, @costePorKg, @costePorUnidad)";

然后,您可以将参数值添加到命令中,如下所示:

cmd.Parameters.AddWithValue("@fecha", DateTime.Today.ToString(System.Globalization.CultureInfo.InvariantCulture));
cmd.Parameters.AddWithValue("@idArticulo", referencia.idArticulo);
cmd.Parameters.AddWithValue("@idColor", referencia.idColor);
cmd.Parameters.AddWithValue("@kgPorUnidad", referencia.kilos);
cmd.Parameters.AddWithValue("@stock", referencia.stockActual);
cmd.Parameters.AddWithValue("@costePorKg", referencia.valorPorKg);
cmd.Parameters.AddWithValue("@costePorUnidad", referencia.valorPorUnidad);

然后将自动识别所有浮点值,并将其妥善存储。

需要注意的一点是,我已将DateTime.Today显式转换为字符串,原因有两个:

  • DateTime不是原始类型,所以我不完全确定数据库引擎会对它做什么。
  • 您已将列Fecha声明为类型TEXT,因此我假设您希望在数据库中使用日期的文本表示,而不是可以“评估”的任何内容。

为了确保您的程序写入相同的数据,无论在哪台机器上执行,我都使用了InvariantCulture CultureInfo实例,它提供了一个可以说的“中性”格式独立于当前机器的文化设置。如果你有程序期望这种格式以防你解析日期,你的应用程序编写的数据库文件将始终兼容,即使在具有不同文化设置的机器上使用该应用程序。

答案 1 :(得分:0)

我可能错了,但也许DefaultThreadCurrentCulture财产可以帮助你。

答案 2 :(得分:0)

我会在.NET端而不是在数据库端解决问题。

在.NET中,数字格式取决于文化。例如:

// This prints 2.3 - Neutral, invariant culture (English notation)
string withDot = (2.3d).ToString(CultureInfo.InvariantCulture.NumberFormat);

// This prints 2,3 - Spanish culture
string withComma = (2.3d).ToString(new CultureInfo("es-ES"));