C#使用System.Data.SQLite读取SQLite字符串列返回科学计数法或类型错误问题
问题成因
- SQLite本身是动态类型系统,采用类型亲和性机制而非强类型约束:即使你将
Zakupki_name、Zakupki_description列声明为字符串类型,只要插入的内容是纯数字格式,SQLite会默认将其识别为INTEGER/REAL(浮点数)类型存储,而非TEXT类型。 - 你当前使用字符串拼接的方式生成插入SQL,没有明确指定参数类型,进一步放大了SQLite的自动类型转换问题:超长的纯数字字符串超出SQLite INTEGER的存储上限时,会自动转成REAL浮点数存储,浮点数转字符串时默认就会输出科学计数法格式,且会丢失尾部精度。
- 读取时抛出
InvalidCast异常的原因是:底层存储的字段类型是浮点数而非字符串,直接调用GetString()属于不同类型的强转,不符合System.Data.SQLite的类型转换规则;调用GetValue().ToString()时,本质是对浮点数执行ToString操作,自然会得到科学计数法的结果。
修复方案
1. 优先替换插入逻辑为参数化查询(核心修复)
完全弃用字符串拼接SQL的方式,通过参数明确指定字段类型,强制SQLite将字符串内容按TEXT类型存储,同时还能避免SQL注入风险。修改后的插入代码示例:
public void InsertZakupku(string name, string description,double value_limit) { try { createConnection(); SQLiteCommand command = new SQLiteCommand( @"INSERT INTO Zakupki ( Zakupki_name, Zakupki_description, Zakupki_update_date, Zakupki_value_limit ) VALUES (@name,@description,@updateDate,@valueLimit);" , connection); // 明确指定参数类型为String,强制存为TEXT command.Parameters.Add("@name", System.Data.DbType.String).Value = name; command.Parameters.Add("@description", System.Data.DbType.String).Value = description; command.Parameters.Add("@updateDate", System.Data.DbType.String).Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); command.Parameters.Add("@valueLimit", System.Data.DbType.Double).Value = value_limit; command.ExecuteNonQuery(); closeConnection(); } catch(Exception ex) { Console.WriteLine(ex.Message); closeConnection(); } }
2. 调整读取逻辑兼容已有数据
如果你的数据库中已经存在历史存储的浮点数格式数据,可以调整读取逻辑,避免异常同时输出非科学计数法的字符串:
while (reader.Read()) { // 读取字符串字段时先判断类型,兼容历史浮点存储的数据 string name = reader.GetFieldType(1) == typeof(double) ? ((decimal)reader.GetDouble(1)).ToString("F0") // 浮点数先转decimal再格式化输出,去掉小数点和科学计数法 : reader.GetString(1); string description = reader.GetFieldType(2) == typeof(double) ? ((decimal)reader.GetDouble(2)).ToString("F0") : reader.GetString(2); zakupkis.Add(new Zakupki( reader.GetInt32(0), name, description, DateTime.Parse(reader.GetString(3)), reader.GetDouble(4) )); }
注意:如果历史数据超出double/decimal的精度范围,已经丢失的精度无法找回,建议从原始数据源重新导入数据。
3. 可选优化建表语句
如果还可以调整表结构,建表时明确将对应字段声明为TEXT类型,而非模糊的string,进一步强化SQLite的TEXT类型亲和性,减少自动类型转换的概率。
内容的提问来源于stack exchange,提问作者Bors1k
相关产品推荐
相关产品推荐

