前記:好吧好吧,我好好的自我檢討,這個總結拖了這麼久才來寫,而且一周多沒有看技術相關的東西,實在罪過,不過因為想做的事情太多,所以時間的分配確實是一個很嚴肅的問題,不是時間不夠用,是我自己沒有做好時間管理,五一之後的分配重心又回歸技術的學習,但是寫小說、學英語也不能放下,所以時間安排就更重要了,an ...
前記:好吧好吧,我好好的自我檢討,這個總結拖了這麼久才來寫,而且一周多沒有看技術相關的東西,實在罪過,不過因為想做的事情太多,所以時間的分配確實是一個很嚴肅的問題,不是時間不夠用,是我自己沒有做好時間管理,五一之後的分配重心又回歸技術的學習,但是寫小說、學英語也不能放下,所以時間安排就更重要了,anyway,乾巴爹!
正文:
進入mainForm窗體後
(1)如果不選擇查詢條件則點擊查詢按鈕,則有MessageBox提示“請選擇條件再搜索”;如果直接點擊上一題或下一題按鈕,則有MessageBox提示“請確定搜索的條件”。
(2)選擇下拉菜單來改變查詢條件,而當下拉菜單的值改變時,顯示查詢題目信息的label會被置空,文本框的顯示內容會改變為”請點擊查詢按鈕進行搜索...“,點擊上一題、下一題的MessageBox提示內容也會改變為”請確定搜索的條件“。
//另外三個下拉菜單的SelectedIndexChanged事件都同科目下拉菜單類似
private void cmbx_subject_SelectedIndexChanged(object sender, EventArgs e) { //如果改變了下拉菜單的值,則表示查詢條件變化,需要將文本框的值改變,且根據文本框中的值,上一題和下一題按鈕將會有不同的提示 rtxbx_show.Text = "請點擊查詢按鈕進行搜索..."; lbl_showNum.Text = ""; }
(3)選擇查詢條件,點擊查詢按鈕
a.沒有查詢到符合條件的題目(查詢相關的資料庫連接等代碼在“b.查詢到符合條件的題目”中講述,這裡只說相關的顯示及提示信息)
文本框顯示內容變為“沒有找到對應題目”,上一題、下一題MessageBox提示內容變為“請換一個條件再查找吧”。
b.查詢到符合條件的題目
1)點擊查詢按鈕,判斷是否查詢條件(下拉菜單的值)全為空,若為空則有MessageBox提示“請選擇條件再搜索”;若不為空則調用jointSQLShow()函數。
//此函數用於拼接 展示 的SQL字元串
string jointSQLShow() { //sql語句相同部分的初始化 string sql_choose = "select * from [questions] where "; //調用jointSQL函數將sql語句拼接 sql_choose += jointSQL(); //返回的拼接好的sql語句,sql語句的拼接 return sql_choose;
}
2)jointSQL函數
a)先定義一個數組sql_arr用於保存下拉菜單選中的值,再定義一個count用於記錄有幾個條件。
//聲明一個數組保存搜索條件(即獲取到的下拉菜單的值) string[] sql_arr = new string[4]; sql_arr[0] = cmbx_subject.Text; sql_arr[1] = cmbx_class.Text; sql_arr[2] = cmbx_grade.Text; sql_arr[3] = cmbx_difficulty.Text; //記錄有幾個搜索條件,根據不同的條件個數進行不同的拼接方法 int count = 0; for (int i = 0; i < sql_arr.Length; i++) { if (sql_arr[i] == "") { continue; } count++; }
b)根據count值的不同,對應不同的拼接方式
//若搜索條件為1個,則根據數據在數組中存儲位置的不同,對應不同的列,以i來記錄下標判斷需要加入的列名稱是什麼
for (int i = 0; i < sql_arr.Length; i++) { if (sql_arr[i] == "") { continue; } //下標為0則對應subject列 if (i == 0) { sql_choose += "subject='" + subject + "'"; } //下標為1則對應quesClass列 if (i == 1) { sql_choose += "quesClass='" + ques_class + "'"; } //下標為2則對應grade列 if (i == 2) { sql_choose += "grade='" + grade + "'"; } //下標為2則對應difficulty列 if (i == 3) { sql_choose += "difficulty='" + difficulty + "'"; } }
//count值為2或3時,需在第二或第三個條件前加“and”連接,拼接的部分與count=1時相同,只是需要多一個判斷,即當前的條件是不是第一個條件
//count值為4時,即所有條件都有
sql_choose += "subject='" +sql_arr[0]+ "' and quesClass='" +sql_arr[1]+ "' and grade='" +sql_arr[2]+ "' and difficulty='" +sql_arr[3]+ "'";
3)將調用jointSQLShow()的值作為實參傳入contactData()中
contactData函數
int contactData(string sql_choose,bool show = true);
//用於此函數返回值,根據傳遞的sql語句的不同而不同 //若sql語句為計數則返回計數的結果,否則返回0 int cou = 0; string connStr = //連接資料庫字元串,根據伺服器的不同而不同; //創建connection對象,用於連接資料庫 SqlConnection conn = new SqlConnection(connStr); //將資料庫連接放入try,catch語句中,防止錯誤導致程式崩潰 try { //打開資料庫連接 conn.Open(); //判斷傳遞的sql語句的類型,若不為count類則進入if語句,否則進入else語句 if(sql_choose.IndexOf("count") == -1) { //創建comm對象傳遞sql命令 SqlCommand comm = new SqlCommand(sql_choose, conn); //將從資料庫獲得的值保存在SqlDataReader中 SqlDataReader ques_result = comm.ExecuteReader(); //如果當前指向的數據存在則進入if,否則進入else if (ques_result.HasRows) { //quesObj[0]=Reader(),quesObj[1]=quesID //quesObj[2]=quesClass,quesObj[3]=quesContent string[] quesInfo = new string[4]; //是否存在數據 quesInfo[0] = ques_result.Read() + ""; //獲取當前數據的quesID值 quesInfo[1] = ques_result.GetInt32(0) + ""; quesId = ques_result.GetInt32(0); //獲取當前數據的subject的值 quesInfo[2] = ques_result.GetString(2); //獲取當前數據的quesContent的值 quesInfo[3] = ques_result.GetString(5); //是否展示在文本框中,預設為true if (show) { //調用將數據展示在文本框中的函數showQues並把存有當前數據信息的quesInfo數組作為參數傳遞 showQues(quesInfo); } } else { //因為沒有查到數據,也需保存此信息 string[] quesInfo = new string[1]; quesInfo[0] = ques_result.Read() + ""; if (show) { showQues(quesInfo); } } //關閉reader對象 ques_result.Close(); } else { //執行計數(count)sql語句,改變cou的值 SqlCommand comm = new SqlCommand(sql_choose, conn); cou = (int)comm.ExecuteScalar(); } } //若資料庫連接出現錯誤,則進入catch語句,並將錯誤提示 catch (Exception ex) { //打開發生異常的處理 MessageBox.Show("出現錯誤:" + ex); } //不論執行try或catch最終都執行finally語句,將資料庫連接關閉 finally { //關閉資料庫的連接 conn.Close(); } //返回cou的值 return cou;
a>若資料庫出錯則會進入catch代碼部分,將錯誤提示在MessageBox里。
b>定義的int cou是用於SQL語句是為了計算符合條件的題目數目。用indexOf("count")則能判斷傳入的SQL語句的類型,若SQL語句不是為了計數,則cou一直為初始值0;若為了計數則會進入最外層的else,執行SQL語句並將結果保存在cou中,作為contactData的值返回。
c>若indexOf("count")為-1則傳入的SQL語句為了查詢題目。定義一個SqlDataReader對象用於查詢資料庫中的題目。若資料庫中有對應SQL語句的數據,則進入內層的if語句,若沒有則進入內層的else語句。contactData的第二個參數預設為true,即將查詢到的數據顯示在文本框中,若show為true則調用showQues函數,並將查詢到的當前的題目的相關信息放到定義的quesInfo數組中作為參數傳遞到showQues函數中。
showQues函數
void showQues(string[] quesObj)//數組參數存儲的值:quesObj[0]=Reader(),quesObj[1]=quesID,quesObj[2]=quesClass,quesObj[3]=quesContent { //是否有數據存在 if (quesObj[0].Trim()=="True") { //獲取題目內容 string str_content = quesObj[3]; //將當前顯示的題目的id值賦給quesId quesId = Convert.ToInt32( quesObj[1]); //判斷題型是否為選擇題,如果是則需進行處理,在選項最前面賦值(A.B.C.D) if (quesObj[2].Trim() == "選擇題") { //在保存數據時,以字元@分隔開題目和每個選項 string[] arr_content = str_content.Split('@'); //每輸出題目或一個選項則換行 rtxbx_show.Text = arr_content[0] + "\n"; //在選項最前面賦值(A.B.C.D) char chooseItem = 'A'; for (int i = 0; i < arr_content.Length - 1; i++) { rtxbx_show.Text += Convert.ToChar(chooseItem + i) + "." + arr_content[i + 1] + "\n"; } } else { //如不為選擇題則直接輸出到文本框 rtxbx_show.Text = str_content + "\n"; } } else { //資料庫中沒有符合條件的數據 rtxbx_show.Text = "沒有找到對應題目"; } }
4)調用jointSQLCount()函數拼接計數的SQL語句,並將其作為參數傳入contactData函數中,contactData函數返回符合查詢條件的題目的總個數。
jointSQLCount函數
string jointSQLCount() { //sql語句相同部分的初始化 string sql_choose = "select count(*) from [questions] where "; //調用jointSQL函數將sql語句拼接 sql_choose += jointSQL(); return sql_choose; }
5)若返回的題目總個數不為0,則定義一個數組ques_arr該數組長度的長度為quesNum,用於保存符合條件題目的quesId值。
6)改變label的值,"查詢題目總數為【" + quesNum + "】個/當前為第【" + currentNum + "】個";
c.點擊下一題或上一題按鈕(兩個按鈕功能類似,只是改變判斷數組邊界的條件,在此只講下一題的代碼)
1)判斷currentNum是否小於ques_arr.Length,若不小於,則提示“沒有下一題了”
2)若小於,則ques_arr中下一個quesId取出作為參數傳入jointSQLId函數中,並改變label的值。