【问题标题】:Can't read float value from SQL Server database无法从 SQL Server 数据库中读取浮点值
【发布时间】:2017-11-23 23:41:27
【问题描述】:

我使用 SQL Server 构建我的数据库并使用 SqlDataReader 从中读取数据。

command.Connection = cn;
command.CommandText = "SELECT * FROM test";
SqlDataReader rd = command.ExecuteReader();
while(rd.Read())
{
    double d = (double) rd.GetValue(0);
}

我试图从中获取值的列 (0) 是 'float' 类型,并且具有值 '3.5' 。作为来自此MSDN link 的映射数据类型,rd.GetValue(0) 返回的对象类型必须为'double'。但是上面的代码返回变量'd'值'0.0'。我试过这条线:

double d = Convert.ToDouble(rd.GetValue(0));

但它仍然将“0.0”返回给变量“d”。

我尝试在 Google 和 StackOverflow 上搜索,但没有结果。

我错过了什么?帮帮我!

【问题讨论】:

  • 给定表中是否只有 1 个条目?如果没有订单,您无法验证是否确实返回了字段值 = 3.5 的行,以防您的表上有多个记录
  • 尝试使用 GetDouble 而不是 GetValue
  • @apomene 我通过放置断点进行检查并进入调试模式,rd.GetValue(0) 的对象确实是 '3.5' 并且类型为 'object {double}'。
  • @PhạmThành 我的问题仍然存在......你只有 1 行吗?例如,如果您有 3 行,是的,您可以在调试模式下将此对象设置为第 1 行或第 2 行的 3,5,但您的代码采用上次迭代的值
  • 你实际上在用 d 做什么?目前d 立即超出范围,因此无法立即看出您对这段代码的实际期望......如果您有类似的功能正在工作,那么比较两者并找出区别是什么。编码不是魔法。它做你告诉它的事情,你清楚地在你的代码中告诉它两件不同的事情。如果您真的找不到差异,请在问题中发布两种方法,我们可以为您找出差异(尽管您真的不需要这个)。

标签: c# .net sql-server casting type-conversion


【解决方案1】:

就像现在一样,您的代码会遍历所有记录(如果有很多)并获取最后一个条目,因为您没有 order by 子句,因此每次查询执行时可能会有所不同。如果您确实只想取 1 个值,请使用 ExecuteScalarorder by 子句:

command.Connection = cn;
command.CommandText = "SELECT  TOP 1 * FROM test order by myfield desc"; //or asc
double result = (double)command.ExecuteScalar();

否则将所有结果保存在列表中:

...

List<double> result = new List<doulbe>();
while(rd.Read())
{
    result.Add(double.Parse(rd[0].ToString());
}

最后,如果您只需要第一个字段,出于性能原因,最好不要使用 * 而是明确设置您想要的字段:

"SELECT  TOP 1 myfield  FROM test order by myfield desc"; //or asc

【讨论】:

    【解决方案2】:

    你可以试试;

    double d = (double) rd.GetValue(0);
    

    double d = 0;
    double.TryParse(rd["ColumnName"].ToString().Replace('.',','),out d);    
    

    或者:

    double d = double.Parse(rd["ColumnName"].ToString(), CultureInfo.InvariantCulture); 
    

    【讨论】:

    • 一个好的答案不只是提供一段代码,它解释了你做了什么以及为什么。如果你不这样做,那么就不可能从答案中学习(或者至少更难)。
    • 我找到了解决方案,并发布了关于它的答案。顺便说一句,非常感谢!
    【解决方案3】:

    这对我来说很好,我在我的列表中得到了 3,5

    List<double> columnData = new List<double>();
                using (SqlConnection connection = new SqlConnection("Server=EGC25199;Initial Catalog=LegOgSpass;Integrated Security=SSPI;Application Name=SQLNCLI11.1"))
                {
                    connection.Open();
                        string query = "SELECT * FROM [dbo].[floattable]";
                    using (SqlCommand command = new SqlCommand(query, connection))
                    {
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                columnData.Add(reader.GetDouble(0));
    
                            }
                        }
                    }
                }
    

    【讨论】:

    • 你的第一行让我很困惑。浮点数是十进制数。它的显示将取决于您的文化。对我来说,三个半是“3.5”。对于使用, 作为小数分隔符的其他人,它可能是“3,5”。也许我误读了你在说什么,我不确定。您还应该解释为什么您认为您的新代码更好。我看到您使用的是GetDouble 而不是GetValue。也许您应该在回答中解释这一点,以及为什么您认为这更好。
    • 我从来没有说它更好。它是对您正在运行的解决方案的答案。浮动是基于我的坏文化的原因,我将删除它。
    • @Chris GetDouble 将按原样获取数据类型。 GetValue 将值保存在对象中,因此您必须进行转换以使其与您想要的匹配。链接在这里:stackoverflow.com/questions/37344167/…
    • @Chris 答案不需要更好。也有很多方法可以解决一个问题。我用我的方式解决了一个问题。如果你想使用 GetValue 或 GetDouble 是相当有偏见的。
    • 我所说的“更好”是指与 OP 无法运行的代码相比。您已经做出了您认为可以解决问题的更改,您应该尝试解释它们是什么,而不是仅仅提供一个大代码块并依靠 OP(和其他任何人)查看您的代码并计算出您所做的更改以及为什么它们在原始代码不起作用时起作用。
    【解决方案4】:

    哦,我找到了答案。我写的代码没有错。问题是我将断点放在'double d = (double) rd.GetValue(0)' 行。也就是说,尚未分配“d”值,因此在调试屏幕上它返回“0.0”。 很抱歉这个错误,感谢所有 Stack-Over-flowers 花费您的时间帮助我!!!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多