SQL Server数据库以指数形式存储数字数据

本文关键字:存储 数字 数据 指数 Server 数据库 SQL | 更新日期: 2023-09-27 18:05:19

我有一个简单的控制台应用程序,它使用OpenXML读取excel文件(source.xlsx),并使用ADO执行SQL插入。. NET将数据保存到SQL Server数据库。

我发现一个问题,当我读一个十进制数字,如0.00015,其中保存到SQL Server后,它将被保存为"1.5 E-2",而不是0.00015。

当我尝试在生产环境中运行它时,会出现这个问题,但当我尝试在登台环境中运行它时不会出现这个问题(在登台环境中,它被保存为0.00015)。

至于环境之间的差异,我还没有发现任何有用的东西,到目前为止所有的设置看起来都是一样的(我很可能遗漏了一些重要的东西)。

以这种方式存储数据的根本原因可能是什么?如何防止?

SQL Server数据库以指数形式存储数字数据

一个可能的原因是,如果您正在创建SQL Insert语句,使用如下内容:

float value = 0.00015f;
string sql = "INSERT INTO [mytable] ([fieldname]) VALUES (" + value.ToString() + ")";

string sql = string.Format("INSERT INTO [mytable] ([fieldname]) VALUES ({0})", value);

这两个都依赖于。net的字符串格式化来生成有效的SQL,这是不安全的。默认的字符串格式将产生"定点或科学记数法中更紧凑的那个"。所以你有时会得到科学符号(1.5E-5),有时会得到定点格式(0.00015)。您可能在服务器和开发环境上有不同的文化,这可能会影响哪种格式更紧凑。

正确的方法是在SQL中使用参数,以避免格式化问题和SQL注入:

using (var cmd = dbConnection.CreateCommand()) {
    var prm = cmd.CreateParameter();
    prm.ParameterName = "value";
    prm.DbType = DbType.Single;
    prm.Direction = ParameterDirection.Input;
    prm.Value = 0.00015f;
    cmd.Parameters.Add(prm);
    cmd.CommandText = "INSERT INTO [mytable] ([fieldname]) VALUES (@value)";
    cmd.ExecuteNonQuery();
}