2011-05-19 97 views
0

我有三個表,我的要求是通過使用每個表的父記錄獲取他們的記錄。在C#和連接打開SQL嵌套查詢問題

所以我有三個查詢。下面是一個代碼示例:

首先查詢

SQLConnection con = new SQLConnection("connectionstring"); 

SQLCommand cmd1 = new SQLCommand (1stQuery,con); 
SQLDataReader rs1 = cmd1.DataReader(); 

while (rs1.Read()) { 

// Making 2nd Query, 2nd Query is using 1st Query result 

SQLCommand cmd2 = new SQLCommand(2ndQuery,con); 
SQLDataReader rs2 = cmd2.DataReader(); 

while (rs2.Read()){ 

//Making 3rd Query using 2nd Query result 
} 
} 

它提供的是已經有一個開放的DataReader錯誤。我不想關閉SQL連接併爲每個查詢打開它,因爲這對性能不利。

我想只爲所有查詢使用一個SQL連接。

+0

很可能是你能達到你想要使用SQL加入(看它在W3Schools的爲例)的東西,讓你得到的信息,你想在一個單一的電話 - 這是很難說沒有實際的代碼你」重新使用。 – 2011-05-19 05:59:11

回答

1

我建議使用ExecuteDataSet。它將包含所有三個查詢的結果。移動,這些查詢應該在存儲過程中執行。

否則您邀請的SQL注入

Sql Injections

2

如果你嵌套調用數據庫,你將需要使用不同的連接。

您在這裏有一個糟糕的問題,在一個循環的數據庫調用 - 也被稱爲N+1 problem

我建議重寫你的數據庫和應用邏輯 - 使用數據庫聯接到單獨的查詢合併成一個,並改變使用結果的邏輯。

+0

我不能在這裏使用任何連接,要求是數字公式需要應用,我認爲它的Npower3,N X N X N.每個循環將有數量的數字被執行。 – 2011-05-19 05:59:10

+0

@Muhammad Atif Agha - 調用數據庫的嵌套循環會導致性能下降,而不是使用第二個連接。 – Oded 2011-05-19 06:01:31

+0

所以你建議!是的,它殺死了表演。 – 2011-05-19 06:11:30

3

您不需要關閉連接。問題(如錯誤所示)是在開始下一個之前,您沒有關閉一個DataReader。

由於奧德說,你有一個「選擇N + 1」的問題,但讓我們忽略的是對這個答案的緣故。

做最簡單的事情是讀取整個第一數據集到內存中,你開始閱讀在下單前:

var list1 = new List<Foo>(); 
using (var rdr1 = cmd1.ExecuteReader()) 
{ 
    list1.Add(...); 
} 

var list2 = new List<Bar>(); 
var cmd2 = ...; 
foreach (var item in list1) 
{ 
    // assign parameters to cmd2 from item 

    using (var rdr2 = cmd2.ExecuteReader()) 
    { 
     list2.Add(...); 
    } 
} 

...等等。

另一種選擇是讓你的連接,它可以讓你有多個活動的DataReader同時在MARS。這幾乎總是一個壞主意,所以讓我們假裝我從來沒有提出過。

1

設置連接字符串爲真,但你的代碼的性能MultipleActiveResultsets性能差。嘗試在存儲過程中包裝查詢以避免循環。