2011-08-22 31 views
13

讀取結果的時候,我的存儲過程:無效的轉換異常從SqlDataReader的

@UserName nvarchar(64), 

    AS 

    BEGIN 
    SELECT MPU.UserName, SUM(TS.Monday)as Monday //TS.Monday contains float value 
    FROM dbo.MapTask MT JOIN dbo.MapPU MPU 
    ON MPU.ID = MT.MPUID 
    JOIN dbo.TimeSheet TS 
    ON MT.TMSID = TS.ID 
    WHERE MT.StartDate = @StartDate_int and MPU.UserName = @UserName 
    GROUP BY MPU.UserName 
    END 

在我的C#代碼

SqlDataReader reader = command.ExecuteReader(); 

     while (reader.Read()) 
     { 
      float monday = (float)reader["Monday"]; // Invalid cast exception 
     } 

有人可以告訴我,我做錯了什麼?謝謝。

+0

您可以嘗試Convert.ToFloat(reader [「Monday」]。ToString()); – Jethro

+0

@Jethro:雖然這是一種非常可怕的方式。當轉換失敗時,用* 2 *轉換替換它(字符串和字符串)通常不是一個好主意。 –

+0

@Jon Skeet,這是有道理的,加上Convert.ToFloat不存在。需要更謹慎。如果Convert.ToFloat確實存在,那麼最好這樣做。 Convert.ToFloat(讀取器[ 「星期一」]); ?? – Jethro

回答

30

我的猜測是價值被返回爲盒裝double而不是float。當你的箱子的類型必須是正好的權利。因此,假如我是對的,它不是decimal或類似的東西,你可以使用:

float monday = (float) (double) reader["Monday"]; 

,它會工作。雖然這很醜陋。如果你使用SqlDataReader.GetFloat它應該是正確的如果它是真正的單精度值,它更清晰(IMO)發生了什麼。

在另一方面,你的數據可能實際上是未來從數據庫返回的double,在這種情況下,你應該(IMO)使用方法:

float monday = (float) reader.GetDouble(column); 

順便說一句,你確定float實際上是這裏最適合的類型嗎?通常decimal更合適...

+14

如果SQL Server中的數據類型是「float」,那麼調用SqlDataReader.GetFloat會不幸會引發錯誤,因爲命名約定是完全不兼容的。 SQL「float」實際上是雙精度值,因此映射到.NET double。 SQL「真實」是映射到.NET浮點的單精度。 .NET的名稱在內部不一致,而不是選擇「double」和「single」作爲關鍵字,它將「float」混合在一起,而在SQL中它是「float」和「real」,不涉及雙精度或單精度。 – Triynko

11

sql float是一個.NET Double,請參閱msdn。 嘗試鑄造成雙。

+0

你可以嘗試使用double來浮動,這就是我所做的。 – TheGateKeeper

+0

這是正確的答案。因爲SQL服務器分別使用「float」和「real」來引用double和single-precision值,所以發生強制轉換異常。我想這是嘗試調用SqlDataReader的常見錯誤。GetFloat在SQL「float」字段上,因爲這樣做很有意義,但是,可惜的是,您必須調用SqlDataReader.GetDouble。如果您打算存儲單精度值,則返回數據庫將類型從「float」更改爲「real」。他們應該堅持「float32」,「float64」,「int32」,int64「而不是所有這些」小「」小「」大「」真「」單「」雙「廢話。 – Triynko

1

我也有過類似的問題,最終做此:

if (!oDR.IsDBNull(0)) 
    Rating = (float)oDR.GetSqlDecimal(0).Value; 

oDR.GetFloat(0)正在恢復和訪問SELECT AVG(...)的結果時無效強制轉換異常

HTH