【问题标题】:How to get float value with SqlDataReader?如何使用 SqlDataReader 获取浮点值?
【发布时间】:2016-09-17 13:41:00
【问题描述】:

在我的数据库中,我将 NextStatDistanceTime 值作为浮点数。执行“float time = reader.GetFloat(0);”行时,报错

系统无效转换异常

如何从这段代码中的 sql 命令获取浮点值?

这是我的代码:

using (SqlConnection conn = new SqlConnection(@"<myconnectionstring>"))
{
    float totaltime = 0;
    for (int i = startStationIndex; i < endStationIndex; i++)
    {
        SqlCommand command = new SqlCommand("SELECT NextStatDistanceTime FROM [MetroDatabase].[dbo].[MetroStation] WHERE StationIndex = " + i + "", conn);
        try
        {
            conn.Open();
            command.ExecuteNonQuery();
            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    float time = reader.GetFloat(0);
                    totaltime = totaltime + time;
                    conn.Close();
                }
            }                        
        }
        catch (Exception ex)
        {
            result = ex.Message;
            Console.WriteLine(ex.Message);
        }
    }

}

【问题讨论】:

  • 数据库中的类型是什么?
  • @JonSkeet 他提到了它,它在数据库中的“浮动”。
  • @RanjitSingh:哎呀,错过了。在那种情况下,我真的希望它会很好......我的猜测是它不是真的数据库中的浮点数。知道调用reader.GetValue(0) 的结果会很有趣——那是什么类型?
  • 顺便说一句,您应该立即开始使用参数化 SQL。
  • 哦,为什么不让数据库为你求和呢?获取所有值似乎很奇怪,只是将它们相加......

标签: c# sql casting reader


【解决方案1】:

我想是时候来张小桌子了。

T-SQL type name .NET equivalent C# type name DataReader method
FLOAT System.Double double IDataReader.GetDouble()
REAL System.Single float IDataReader.GetFloat()

注意GetFloat 的名称有误——它应该是GetSingle,因为float 是C# 特定的名称。例如,它在 VB.NET 中毫无意义。

因此,如果您的数据库列的类型为 FLOAT,请使用 GetDouble 而不是 GetFloat 读取它。数据读取器方法执行转换;有一个通用的GetValue 方法可以将值作为object 获取,然后您可以进一步转换。

顺便说一句,这不是唯一的微妙之处——.NET 浮点类型支持denormalized values,而 T-SQL 类型不支持,因此可以在 .NET 代码中使用浮点数即使类型匹配也无法成功存入数据库。

【讨论】:

  • 你可以找到表here ;-)
  • @TimSchmelter:这是一个略有不同的表,因为它还描述了到 ADO.NET SQL 特定类型的映射。 SqlSingleSystem.Single 不同。为了完整起见,我可以将它包含在我的表中,但很少需要使用这些类型,除非没有相应的 .NET 系统类型(如 SqlGeography)。但是,是的,这是需要注意的另一层转换。
【解决方案2】:

您可以阅读 here 一个 sql-server 浮点映射到一个 .NET 双精度,所以您需要使用 GetDouble

double totaltime = 0;  // necessary, double is wider than float
// ...

while (reader.Read())
{
    double time = reader.GetDouble(0);
    totaltime = totaltime + time;
    // conn.Close(); no, not in this loop, should be closed in the finally or via using-statement
}

【讨论】:

    【解决方案3】:

    我的猜测是数据库返回双精度值,尝试将其设为 Double 并将其转换为 float(如果需要)。

    float time= (float) reader.GetDouble(0);
    

    【讨论】:

      【解决方案4】:

      你可以试试:

      float time = float.Parse(reader[0].ToString());
      

      另请注意(尽管与您的 Q 无关)您不需要运行

      command.ExecuteNonQuery();
      

      【讨论】:

        【解决方案5】:

        试试这个

        convert.ToSingle(reader["NextStatDistanceTime"])
        

        或者做

        double value = (double)reader["NextStatDistanceTime"]
        

        sql的float相当于c#的double,可以看到类似的映射here

        【讨论】:

          【解决方案6】:
           while (reader.Read())
           {
               object initialTime = reader["NextStatDistanceTime"];
               float time;
               float.TryParse(initialTime.ToString(), out time);
          
               totaltime = totaltime + time;
               conn.Close();
           }
          

          试试这个,这将从数据库中获取时间,然后将其转换为浮点数,如果需要,您可以将 reader["NextStatDistanceTime] 放在 tryparse 中,但为了更清楚,我已经这样做了。

          有什么问题告诉我

          【讨论】:

          • @TimSchmelter 解释一下?
          • 参见例如@Hari Prasad 的回答。无需解决此问题。
          • 这不仅没有必要,而且有潜在的危险。假设它已经作为字符串从数据库返回,使用 . 作为小数分隔符,但 OP 使用的文化使用 , 作为小数分隔符...
          • @RenéVogt 和 Tim Schmelter 你能解释一下为什么这是一个不必要的解决方法吗?
          • @JonSkeet 好的,这是有道理的,否则它将无法转换为浮点数,并且可能必须在将其用作浮点数之前对其进行验证以检查它是否包含','或类似的东西
          【解决方案7】:

          可能是数据库类型和 c# 类型之间的精度不匹配。 尝试像(float)reader.GetDouble(0);这样的演员

          【讨论】:

            猜你喜欢
            • 2019-09-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多