2016-07-28 53 views
0

美好的一天!Sql查詢數據讀取器返回True,即使它在C#中也是False!

這花了我幾個小時,爲什麼我的查詢返回一個真實的,即使它是假的。

這裏是我的代碼。

public SqlDataReader Check(BEL bel) { 
     SqlCommand cmd = new SqlCommand(); 
     cmd.Connection = dbcon.getcon(); 
     cmd.CommandType = CommandType.Text; 
     cmd.CommandText = "SELECT SUM(Total) as OverallTotal FROM table WHERE [email protected] AND [email protected] AND [email protected] AND Status='Without'"; 
     cmd.Parameters.AddWithValue("@Id",bel.CLEmpID); 
     cmd.Parameters.AddWithValue("@From", bel.CLPayrollFrom); 
     cmd.Parameters.AddWithValue("@To", bel.CLPayrollTo); 

     SqlDataReader dr = cmd.ExecuteReader(); 
     return dr; 
    } 

假設參數值是:

@Id = 0001 
@From = 1/28/2016 
@To = 1/29/2016 

這裏是我的方法調用DataReader的

SqlDataReader drCheck; 

drCheck = bal.Check(bel); 
if (drCheck.HasRows == true) 
{ 
    drCheck.Read(); 
    // I'm inside the computation of OverallTotal 
}else{ 
    drCheck.Close(); 
    // I'm out 
} 
drCheck.Close(); 

的問題是,當我 「到」 值,例如,是假設它是假的,它不符合真實條件,但事實並非如此。

請幫忙。在此先感謝

+0

如果讀者沒有行,則關閉兩次 –

+0

現在沒關係。問題是,爲什麼即使查詢是錯誤的,它仍然發送給我內部的if == true –

+0

爲什麼你需要else部分?查詢總是返回一個結果。你甚至不需要'SqlDataReader'。使用'ExecuteScalar'。 – user3185569

回答

1

你的情況,你並不需要一個閱讀器,你可以使用的ExecuteScalar:

public decimal? Check(BEL bel) 
{ 
    SqlCommand cmd = new SqlCommand(); 
    cmd.Connection = dbcon.getcon(); 
    cmd.CommandType = CommandType.Text; 
    cmd.CommandText = "SELECT SUM(Total) as OverallTotal FROM table WHERE [email protected] " + 
         "AND [email protected] AND [email protected] AND Status='Without'"; 
    cmd.Parameters.AddWithValue("@Id", bel.CLEmpID); 
    cmd.Parameters.AddWithValue("@From", bel.CLPayrollFrom); 
    cmd.Parameters.AddWithValue("@To", bel.CLPayrollTo); 

    object obj = cmd.ExecuteScalar(); 
    decimal? value = null; 
    if (obj != DBNull.Value) 
     value = Convert.ToDecimal(obj); 

    return value; 
} 

decimal? total = bal.Check(bel); 
if (total.HasValue) 
{ 
    // do something with the total.Value 
} 
else 
{ 

} 
+0

它仍然送我到/ /我是部分。 :( –

+0

@mark檢查編輯 – user3185569

+0

不幸的是,它不起作用,它仍然把我發送到if(drCheck.Read())。 –

2

在您的查詢,你有合計函數。無論你從&返回沒有行,因爲你有聚合函數,你總是得到一行的值至少爲零。

+0

您認爲我應該怎麼做才能讓數據讀取者將假查詢發送到else條件? :/ –

+0

@Barani,空集的總和將重新設置爲NULL不爲零。 – Serg

+0

是的,當我改變我的To = 1/30/2016時,它說,Object不能從DBNull轉換爲其他類型。 –

1

即使沒有匹配記錄,您的查詢始終會返回一個值,因爲您正在對它們進行求和,所以如果沒有記錄,並且在所有匹配記錄的值爲NULL的情況下,您將得到NULL。如果有記錄且總和結果爲0(包括NULL的值將被計爲0),您將得到0。

你可以使用下面使用不同的查詢返回兩個信息的方法:

public bool GetOverAll(int id, DateTime payrollFrom, DateTime payrollTo, out double? overall) 
{ 
    overall = null; 
    string sql = @" 
    ;WITH Data AS(
     SELECT t.* 
     FROM table 
     WHERE Id  = @Id 
     AND DateFrom = @From 
     AND DateTo = @To 
     AND Status = 'Without' 
    ) 
    SELECT HasRows = CAST(CASE WHEN EXIST(SELECT 1 FROM CTE) 
          THEN 1 ELSE 0 END AS bit), 
      OverallTotal = SUM(Total) 
    FROM CTE"; 

    using (var con = new SqlConnection("connectionstring")) 
    using (var cmd = new SqlCommand(sql, con)) 
    { 
     cmd.Parameters.AddWithValue("@Id", id); 
     cmd.Parameters.AddWithValue("@From", payrollFrom); 
     cmd.Parameters.AddWithValue("@To", payrollTo); 
     con.Open(); 
     using (var rd = cmd.ExecuteReader()) 
     { 
      if (rd.Read()) 
      { 
       bool hasRows = rd.GetBoolean(0); 
       if (!rd.IsDBNull(1)) 
        overall = rd.GetDouble(1); 
       return hasRows; 
      } 
      else 
      { 
       throw new Exception("This should never be the case!"); 
      } 
     } 
    } 
} 

現在您知道是否有匹配的記錄或不:

double? overall; 
bool hasRows = GetOverAll(id, payrollFrom, payrollTo, out overall); 
if(hasRows && overall.HasValue) 
{ 
    // matching records and the sum of these values was not NULL (possible if nullable column and all values were NULL) 
    double total = overall.Value; 
} 
+0

如果沒有記錄,則爲0,但爲NULL;否則,如果列爲空,則可能爲NULL – Serg

+0

如果所有選定的行都爲NULL,那麼? – Serg

+0

@serg:ok,好點:)編輯我的答案 –

1

看簡單的例子

SELECT SUM(total1) as tt1, SUM(total2) AS tt2, COUNT(*) AS [Nbr of rows] 
FROM (
    SELECT 10 AS total1, CAST(NULL AS INT) total2 -- 
    ) t 
--WHERE 1=2 

通常,當SUMmed列可爲空時,只有COUNT(*)會告訴區別在於選擇了任何行或未選擇行。

+0

I' m現在使用ExecuteScalar,從這裏回答的人之一。問題是當值OverallTotal是0,所以它必須去假,但我得到了這個錯誤「附加信息:對象不能從DBNULL轉換爲其他類型。在返回Convert.ToDecimal(cmd.ExecuteScalar())時,從2016年1月29日至2016年1月30日選擇不同的「To」值:(「 –

+0

因此,即使值爲0,它仍然會將我發送給if!= 0條件 –

+0

從業務角度來看,您需要決定這些情況(沒有行,有些行返回NULL,有些行返回0)是相同的還是應該區別對待。最後一種情況下,您需要DataReader ,否則ExecuteScalar已經足夠了。 – Serg

相關問題