
圖一
圖二
圖表 1 與 2 所示的程序示范如何取得數據命令所傳回的兩個結果集,并將這兩個結果集之所有數據記錄之所有字段的內容顯示于窗體上的 TextBox 控件中。
本范例將兩道 SELECT 表達式指派給 SqlCommand 對象的 CommandText 屬性,因此在使用 ExecuteReader 方法執行數據命令后會傳回兩個結果集。我們藉由調用 SqlDataReader 對象的 NextResult 方法來順序處理各個結果集,而在處理個別的結果集時,則調用 SqlDataReader 對象的 GetName 方法來取得字段名稱(亦即 myReader.GetName(i)),并位置順序傳遞給 SqlDataReader 對象來取得字段的數據內容(亦即 myReader[i])。
特別要說明的是,使用 Using 表達式來執行數據命令,產生 SqlDataReader 對象,并傳回多個數據結果集之后,如果搭配 Do..While 循環來取得結果集所有數據記錄之各字段的名稱與字段的內容時,會出現「當目前沒有資料時,嘗試讀取無效」的錯誤信息。
怎么會發生這個問題呢?問題就出在 Do…While 循環身上。Do…While 循環的特色是,不論指定的判斷表達式之結果是 True 還是 False,至少都會將 { } 內的程序代碼區塊執行一次。換句話說,在沒有執行 myReader.Read() 函式之前,如果先執行 myReader.GetName(i) 函式來取得數據,當然就會發生錯誤。
要解決這個問題,請您將原本的 Do…While 循環改寫為 While 循環,判斷式一樣可以利用 myReader.Read()。相關程序代碼撰寫于窗體的 Load 事件處理例程中,列示如下:
PRivate void CH6_DemoForm010_Load(object sender, EventArgs e)
{
...
try
{
// 建立連接。
using (SqlConnection con = new
SqlConnection(connectStringBuilder.ConnectionString))
{
// 建立數據命令對象(亦即SqlCommand 對象)。
SqlCommand foxCMD = new SqlCommand();
foxCMD.Connection = con;
// 將兩道SELECT 表達式指派給CommandText 屬性,
// 此舉將使得數據命令會傳回兩個結果集。
foxCMD.CommandText = "SELECT * FROM 章立民研究室;SELECT * FROM 客戶";
// 開啟連接。
con.Open();
int resultSetCounter = 1;
StringBuilder s = new StringBuilder();
// 執行會傳回多個結果集的數據命令。
using (SqlDataReader myReader = foxCMD.ExecuteReader())
{
bool fNextResult = true;
// 順序處理各個結果集。
do
{
...
switch (resultSetCounter)
{
case 1:
s.AppendLine("「章立民研究室」數據表的數據記錄");
break;
case 2:
s.AppendLine("「客戶」數據表的數據記錄");
break;
}
...
// 取得結果集所有數據記錄之各字段的名稱與字段的內容。
if (myReader.HasRows)
{
while (myReader.Read())
{
for (int i = 0; i < myReader.FieldCount; i++)
{
s.AppendLine(myReader.GetName(i) + ": " + myReader[i].ToString());
}
...
}
}
// 將數據讀取器前移到下一個結果集。
fNextResult = myReader.NextResult();
resultSetCounter += 1;
}
while (fNextResult);
// 將所取得的數據指派給TextBox 控件的Text 屬性。
txtInfo.Text = s.ToString();
}
}
}
...
}
章立民研究室敬上
期待更多精彩,敬請關注:
http://www.china-pub.com/static/jsj_zlm_060824.html
新聞熱點
疑難解答