2012-10-19 63 views
40

我通常使用DataSet,因爲它非常靈活。最近我分配了代碼優化任務,爲了減少對數據庫的命中,我在一個過程中更改了兩個查詢。一個查詢返回count,另一個返回actual data。也就是說,我的stored procedure返回兩個表。現在,我知道如何使用DataSets來讀取兩個表格,但我需要使用DataReader來讀取兩個表格。在尋找我發現ThisDataReader中的倍數表

我按照文章,寫我的代碼是這樣的:

dr = cmd.ExecuteReader(); 
while (dr.Read()) 
{ 


} 
if (dr.NextResult()) // this line throws exception 
{ 
    while (dr.Read()) 
{ 

但我正在逐漸dt.NextResult異常。例外是:

Invalid attempt to call NextResult when reader is closed. 

我也試圖谷歌上面的錯誤,但仍然無法解決問題。 任何幫助將不勝感激。我需要使用datareader來讀取多個表格,這可能嗎?

+1

什麼,我不明白的是:「一個查詢返回的計數和其他收益的實際數據是,我的存儲過程返回兩個表」 _ _爲什麼是計數(這是一個標量值)**表**? –

+0

是的,它是標量值,但存儲過程是使用動態查詢編寫的。這兩個查詢都非常大,查詢被寫爲varchar,然後最後使用Exec執行。如果我將Count查詢作爲實際數據查詢的子查詢,那麼查詢變量的大小非常大,並且會執行錯誤。所以爲了避免這種情況,我寫了兩個不同的查詢,這就是Count也來自表格的原因(第二個表格)。我希望我說清楚。 –

回答

50

試試這個,因爲這將關閉連接,數據讀取器和命令一次任務得到了,所以這不會給DataReader的密切例外

而且做檢查這樣if(reader.NextResult())檢查有下一個結果,

using (SqlConnection connection = new SqlConnection("connection string here")) 
{ 
    using (SqlCommand command = new SqlCommand 
      ("SELECT Column1 FROM Table1; SELECT Column2 FROM Table2", connection)) 
    { 
     connection.Open(); 
     using (SqlDataReader reader = command.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       MessageBox.Show(reader.GetString(0), "Table1.Column1"); 
      } 

      if(reader.NextResult()) 
      { 
       while (reader.Read()) 
       { 
       MessageBox.Show(reader.GetString(0), "Table2.Column2"); 
       } 
      } 
     } 
    } 
} 
+0

Ÿ有 - 1? –

+0

我沒有投票給你。但我的代碼就像你的代碼一樣。 –

+0

@ muhammadkashif-你的錯誤是因爲你的連接關閉或datareader關閉所以它最好做檢查也是這樣的....也檢查if語句中的nextresultset,因爲我這樣做也可以幫助你... –

11

我試圖重現此問題(也因爲我以前沒有在閱讀器中使用多個表)。但它按預期工作,因此我認爲你已經省略了相關的代碼。

這裏是我的測試代碼:

using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString)) 
{ 
    using (var cmd = new SqlCommand("SELECT TOP 10 * FROM tabData; SELECT TOP 10 * FROM tabDataDetail;", con)) 
    { 
     int rowCount = 0; 
     con.Open(); 
     using (IDataReader rdr = cmd.ExecuteReader()) 
     { 
      while (rdr.Read()) 
      { 
       String object1 = String.Format("Object 1 in Row {0}: '{1}'", ++rowCount, rdr[0]); 
      } 
      if (rdr.NextResult()) 
      { 
       rowCount = 0; 
       while (rdr.Read()) 
       { 
        String object1 = String.Format("Object 1 in Row {0}: '{1}'", ++rowCount, rdr[0]); 
       } 
      } 
     } 
    } 
} 
+0

謝謝,我的問題解決了,爲你的努力投票。 –

+0

如果我想使用DataTable.Load()而不是循環讀取器,那麼第二個表將被填充。任何線索? – Biki

+3

最後我得到了線索。如果我們使用的是DataTable.Load(),那麼我們不需要使用rdr.NextResult(),因爲這是隱含的照顧。 – Biki