我有一个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 。没有错误。
然后数据存储如下:
也就是说,当它没有小数部分时使用点,而当它没有时使用逗号。
这个问题是例如我使用SELECT语句来计算时,例如:
SELECT VS.Fecha, VS.IdArticulo, VS.IdColor, (VS.Stock * (VS.CostePorUnidad + VS.CostePorKg * Vs.KgPorUnidad)) AS Valor FROM valoresStock VS
这给出了以下结果,这是错误的(只用带点的数字)。
所以,如果我在表格中手动更改点的逗号,它就能正常工作。
但是如何让我的应用做到这一点,某种文化改变?
或者我可以让SQLite理解或自动转换逗号吗?
为什么SQLite接受该号码是否有效,如果它以后不理解?
答案 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"));