web-dev-qa-db-ja.com

SqlDataReaderで浮動小数点値を取得するにはどうすればよいですか?

私のデータベースでは、フロートとして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);
        }
    }

}
9

小さなテーブルの時間だと思います。

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

GetFloatはC#固有の名前であるため、GetSingleの名前は間違っています。floatである必要があります。たとえば、VB.NETでは意味がありません。

したがって、データベース列のタイプがFLOATの場合は、GetDoubleではなくGetFloatを使用して読み取ってください。データリーダーメソッドは変換を実行しない。値をGetValueとして取得する汎用のobjectメソッドがあり、さらに変換できます。

ちなみに、これは唯一の微妙な問題ではありません。NET浮動小数点型では 非正規化値 がサポートされていますが、T-SQL型ではサポートされていないため、に浮動小数点数を含めることができます。タイプが一致しても、データベースに正常に格納できないNETコード。

23
Jeroen Mostert

あなたが読むことができるように here sql-server floatは.NET doubleにマップするので、 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
Tim Schmelter

私の推測では、データベースはdouble値を返していると思います。Doubleとして取得し、floatに変換してみてください(必要な場合)。

float time= (float) reader.GetDouble(0);
2
Hari Prasad

これを試して

convert.ToSingle(reader["NextStatDistanceTime"])

またはする

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

SQLのFloatはc#のdoubleに相当します。同様のマッピングを見ることができます here

0
Ranjit Singh

おそらく、データベースタイプとc#タイプの精度が一致していません。 (float)reader.GetDouble(0);のようにキャストしてみてください

0
Kodre

あなたが試すことができます:

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

また、実行する必要がないことに注意してください(ただし、Qとは関係ありません)。

command.ExecuteNonQuery();
0
apomene
 while (reader.Read())
 {
     object initialTime = reader["NextStatDistanceTime"];
     float time;
     float.TryParse(initialTime.ToString(), out time);

     totaltime = totaltime + time;
     conn.Close();
 }

これを試してください。これはデータベースから時間を取得し、それを浮動小数点数に変換します。reader["NextStatDistanceTime]必要に応じてtryparseで使用しますが、より明確にするために、次のようにしています。

問題があれば教えてください

0
Brendon