2016-05-20 3 views
6

В моей базе данных значение NextStatDistanceTime имеет значение float. Когда линия «float time = reader.GetFloat(0);» та или иная строчка, это дает ошибкуКак получить значение float с помощью SqlDataReader?

система недействительного исключение литого

Как я могу получить значение с плавающей точкой из 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); 
     } 
    } 

} 
+3

Какое это изделие? –

+0

@JonSkeet он упомянул об этом, его «float» в базе данных. –

+1

@RanjitSingh: Упс, пропустил это. В этом случае я действительно ожидаю, что все будет хорошо ... Я предполагаю, что это не * действительно * плавающий в базе данных. Было бы интересно узнать результат вызова 'reader.GetValue (0)' - какой тип? –

ответ

12

Это время для небольшого стола, я думаю.

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 можно иметь числа с плавающей запятой, которые невозможно сохранить в базе данных, даже если они совпадают.

+0

Вы можете найти таблицу [здесь] (https://msdn.microsoft.com/en-us/library/ms131092 (v = sql.130) .aspx) ;-) –

+0

@TimSchmelter: это тонко различной таблицы, так как она описывает сопоставление типов ADO.NET SQL-specific. 'SqlSingle' - это не то же самое, что' System.Single'. Я могу включить его в таблицу для полноты, но редко использовать эти типы, если нет соответствующего типа системы .NET (например, 'SqlGeography'). Но, да, это еще один уровень переходов, о котором нужно знать. –

0

вы можете попробовать:

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

также отметить (хотя и не связанные с Q), что вам не нужно запускать

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

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

Попробуйте это, это даст время f rom, затем преобразуйте его в float, вы можете просто поместить reader["NextStatDistanceTime] в tryparse, если хотите, но чтобы сделать его более ясным, я сделал это вот так.

Любые вопросы, дайте мне знать

+2

Это ненужное обходное решение. –

+0

@TimSchmelter объяснить? – Brendon

+0

См., Например, ответ @Hari Prasad. Нет необходимости в этом. –

0

Попробуйте

convert.ToSingle(reader["NextStatDistanceTime"]) 

или сделать

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

поплавка SQL эквивалентно Дублем C#, вы можете увидеть подобное отображение here

0

Вероятно, это точное совпадение между типом базы данных и типом C#. Постарайся отбрасывать как (float)reader.GetDouble(0);

1

Я думаю, что база данных возвращается двойное значение, попробуйте получить его как Double и преобразовать его float (если требуется).

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

Как вы можете прочитать here SQL-сервер-карты с плавающей запятой в .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 
}