2015-10-06 120 views
-1

我有一個問題,直到循環。當記錄成功保存並出現信息框時,點擊確定按鈕後,它只顯示信息框並無限重複。我不知道那是什麼代碼。請幫忙。如何停止循環

 MySqlConn.Open() 
     Dim last, midd, first, age, occu, phone As MySqlDataReader 
     Dim cmd1, cmd2, cmd3, cmd4, cmd5, cmd6, cmd7, cmd8, cmd9, cmd10, cmd11 As New MySqlCommand 
     Dim query1, query2, query3, query4, query5, query6, query7, query8, query9, query10, query11 As String 

     'lastname query 
     query1 = "SELECT * FROM newpatient WHERE Lastname ='" & txtLastname.Text & "'" 
     cmd1 = New MySqlCommand(query1, MySqlConn) 
     last = cmd1.ExecuteReader 

     'first query 
     query2 = "SELECT * FROM newpatient WHERE Firstname ='" & txtFirstname.Text & "'" 
     cmd2 = New MySqlCommand(query2, MySqlConn) 
     last.Close() 
     first = cmd2.ExecuteReader 

     'middle query 
     query3 = "SELECT * FROM newpatient WHERE Middlename ='" & txtMiddlename.Text & "'" 
     cmd3 = New MySqlCommand(query3, MySqlConn) 
     first.Close() 
     midd = cmd3.ExecuteReader 

     'age query 
     query4 = "SELECT * FROM newpatient WHERE Age ='" & txtAge.Text & "'" 
     cmd4 = New MySqlCommand(query4, MySqlConn) 
     midd.Close() 
     age = cmd4.ExecuteReader 

     'gender query 
     query5 = "SELECT * FROM newpatient WHERE Occupation ='" & txtOccupation.Text & "'" 
     cmd5 = New MySqlCommand(query5, MySqlConn) 
     age.Close() 
     occu = cmd5.ExecuteReader 

     'phone query 
     query6 = "SELECT * FROM newpatient WHERE Mobile_Number ='" & txtMobileNumber.Text & "'" 
     cmd6 = New MySqlCommand(query6, MySqlConn) 
     occu.Close() 
     phone = cmd6.ExecuteReader 


     Do While last.HasRows = 0 And first.HasRows = 0 And midd.HasRows = 0 And occu.HasRows = 0 And phone.HasRows = 0 And age.HasRows = 0 

      Dim cmd As MySqlCommand = MySqlConn.CreateCommand 
      cmd.CommandText = String.Format("INSERT INTO newpatient (ID, Lastname, Firstname, Middlename, Age, Mobile_Number, Gender, Address, Occupation, Month, Day, Year)" & 
              "VALUES ('{0}' ,'{1}' ,'{2}' ,'{3}' ,'{4}' ,'{5}' , '{6}', '{7}', '{8}', '{9}', '{10}', '{11}')", 
              txtID.Text, 
              txtLastname.Text, 
              txtFirstname.Text, 
              txtMiddlename.Text, 
              txtAge.Text, 
              txtMobileNumber.Text, 
              cmbGender.SelectedItem, 
              txtAddress.Text, 
              txtOccupation.Text, 
              cmbMonth.SelectedItem, 
              cmbDay.SelectedItem, 
              cmbYear.SelectedItem) 
      phone.Close() 
      Dim affectedrows As Integer = cmd.ExecuteNonQuery() 
      If affectedrows > 0 Then 
       MsgBox("Record successfully saved!", MsgBoxStyle.Information, "Success") 

'AUTO GENERATE RANDOM IDs 
       Dim random As New Random 
       Dim id As Integer 
       id = (random.Next(100000000, 1000000000)) 
       txtID.Text = id 
       'CLEARS TEXTBOXES 
       txtMobileNumber.Text = "" 
       txtLastname.Text = "" 
       txtFirstname.Text = "" 
       txtMiddlename.Text = "" 
       txtAge.Text = 0 
       cmbGender.SelectedItem = "" 
       cmbDay.SelectedItem = "" 
       cmbMonth.SelectedItem = "" 
       cmbYear.SelectedItem = 0 
       txtAddress.Text = "" 
       txtOccupation.Text = "" 
       txtLastname.Select() 
      Else 
       MsgBox("Saving record failed.", MsgBoxStyle.Critical, "Failed") 
       'AUTO GENERATE RANDOM IDs 
       Dim random As New Random 
       Dim id As Integer 
       id = (random.Next(100000000, 1000000000)) 
       txtID.Text = id 
       'CLEARS TEXTBOXES 
       txtMobileNumber.Text = "" 
       txtLastname.Text = "" 
       txtFirstname.Text = "" 
       txtMiddlename.Text = "" 
       txtAge.Text = 0 
       cmbGender.SelectedItem = "" 
       cmbDay.SelectedItem = "" 
       cmbMonth.SelectedItem = "" 
       cmbYear.SelectedItem = 0 
       txtAddress.Text = "" 
       txtOccupation.Text = "" 
       txtLastname.Select() 
      End If 
     Loop 
     'CLEARS TEXTBOXES 
     txtMobileNumber.Text = "" 
     txtLastname.Text = "" 
     txtFirstname.Text = "" 
     txtMiddlename.Text = "" 
     txtAge.Text = 0 
     cmbGender.SelectedItem = "" 
     cmbDay.SelectedItem = "" 
     cmbMonth.SelectedItem = "" 
     cmbYear.SelectedItem = 0 
     txtAddress.Text = "" 
     txtOccupation.Text = "" 
     MsgBox("Patient has already registered!", MsgBoxStyle.Critical, "Already registered") 

     MySqlConn.close() 
+1

曾聽說過[Single responsibility原則(https://en.wikipedia.org/wiki/Single_responsibility_principle)?或[SQL注入攻擊](https://imgs.xkcd.com/comics/exploits_of_a_mom.png)? – user3697824

+0

爲什麼你的循環是無止境的(也稱爲無限循環)的原因是你設置的標準。閱讀器上的'HasRows'屬性永遠不會改變 - 它在執行命令時設置。由於您正在做一個select來查看記錄是否已經存在,並且如果他們沒有,那麼您插入,您會反覆插入。你不需要'Do'循環 - 這是錯誤的分支機制。 – Tim

回答

1

要停止循環,需要調用退出,就像這樣:

Exit Do 

說了這麼多,你永遠不應該只是調用exit,而不需要一個條件得到滿足,否則你可能會遇到意想不到的行爲。

但是你在這裏有很多更大的問題。我將盡快列出它們,幷包含一個快速僞代碼建議(如我在.NET中從未使用過MySql,因此完全不熟悉API,所以在代碼工作之前需要修改此代碼)

Dim cmd As MySqlCommand = MySqlConn.CreateCommand 
cmd.CommandText = "INSERT INTO newpatient (ID, Lastname, Firstname, Middlename, Age, Mobile_Number, Gender, Address, Occupation, Month, Day, Year)" & 
        "VALUES (:ID, :Lastname, :Firstname, :Middlename, :Age, :Mobile_Number, :Gender, :Address, :Occupation, :Month, :Day, :Year)" 
cmd.Parameters.Add(new MySqlParameter(":ID", txtID.Text)) 
cmd.Parameters.Add(new MySqlParameter(":Lastname", txtLastname.Text)) 
cmd.Parameters.Add(new MySqlParameter(":Firstname", txtFirstname.Text)) 
cmd.Parameters.Add(new MySqlParameter(":Middlename", txtMiddlename.Text)) 
cmd.Parameters.Add(new MySqlParameter(":Age", txtAge.Text)) 
cmd.Parameters.Add(new MySqlParameter(":Mobile_Number", txtMobileNumber.Text)) 
cmd.Parameters.Add(new MySqlParameter(":Gender", cmbGender.SelectedItem)) 
cmd.Parameters.Add(new MySqlParameter(":Address", txtAddress.Text)) 
cmd.Parameters.Add(new MySqlParameter(":Occupation", txtOccupation.Text)) 
cmd.Parameters.Add(new MySqlParameter(":Month", cmbMonth.SelectedItem)) 
cmd.Parameters.Add(new MySqlParameter(":Day", cmbDay.SelectedItem)) 
cmd.Parameters.Add(new MySqlParameter(":Year", cmbYear.SelectedItem)) 

Dim affectedrows As Integer = cmd.ExecuteNonQuery() 
If affectedrows = 1 Then 
    MsgBox("Record successfully saved!", MsgBoxStyle.Information, "Success") 
Else 
    If affectedrows = 0 Then 
     'Most likely the record already existed, call an update here and if you get 1 result, the record existed and you just saved changes 
     MsgBox("Patient has already registered!", MsgBoxStyle.Critical, "Already registered") 
     'You could change the above to a Yes/No question about updating the record and have the result in an if to update the record at the user's discretion. 
     cmd = MySqlConn.CreateCommand 
     cmd.CommandText = "UPDATE newpatient " & 
          "SET Lastname = :Lastname, Firstname = :Firstname, Middlename = :Middlename, Age = :Age, Mobile_Number = :Mobile_Number, " & 
          "  Gender = :Gender, Address = :Address, Occupation = :Occupation, Month = :Month, Day = :Day, Year = :Year " & 
          "WHERE ID = :ID" 
     cmd.Parameters.Add(new MySqlParameter(":ID", txtID.Text)) 
     cmd.Parameters.Add(new MySqlParameter(":Lastname", txtLastname.Text)) 
     cmd.Parameters.Add(new MySqlParameter(":Firstname", txtFirstname.Text)) 
     cmd.Parameters.Add(new MySqlParameter(":Middlename", txtMiddlename.Text)) 
     cmd.Parameters.Add(new MySqlParameter(":Age", txtAge.Text)) 
     cmd.Parameters.Add(new MySqlParameter(":Mobile_Number", txtMobileNumber.Text)) 
     cmd.Parameters.Add(new MySqlParameter(":Gender", cmbGender.SelectedItem)) 
     cmd.Parameters.Add(new MySqlParameter(":Address", txtAddress.Text)) 
     cmd.Parameters.Add(new MySqlParameter(":Occupation", txtOccupation.Text)) 
     cmd.Parameters.Add(new MySqlParameter(":Month", cmbMonth.SelectedItem)) 
     cmd.Parameters.Add(new MySqlParameter(":Day", cmbDay.SelectedItem)) 
     cmd.Parameters.Add(new MySqlParameter(":Year", cmbYear.SelectedItem)) 
     affectedrows = cmd.ExecuteNonQuery() 
     If affectedrows = 1 Then 
      MsgBox("Record successfully saved!", MsgBoxStyle.Information, "Success") 
     Else 
      MsgBox("Saving record failed.", MsgBoxStyle.Critical, "Failed") 
     End If 
    Else 
     'Should never get here. We covered 0 and 1 in the other two logic branches. 
     'In this small demo, handling when more than 1 record gets updated is out of scope. 
    End If     
End If 


'CLEARS TEXTBOXES 
txtMobileNumber.Text = "" 
txtLastname.Text = "" 
txtFirstname.Text = "" 
txtMiddlename.Text = "" 
txtAge.Text = 0 
cmbGender.SelectedItem = "" 
cmbDay.SelectedItem = "" 
cmbMonth.SelectedItem = "" 
cmbYear.SelectedItem = 0 
txtAddress.Text = "" 
txtOccupation.Text = "" 
txtLastname.Select() 

MySqlConn.close() 
  1. 永遠無法從那裏你依靠一些這些字符串的用戶串查詢。這會讓你容易受到SQL注入攻擊(嘗試在其中一個名稱字段中輸入一個帶有撇號的名稱,並觀察錯誤亂舞,然後意識到有惡意的人可能會對數據庫造成嚴重損壞,如果不清理您的輸入)儘可能地查詢您的查詢!

  2. 不要重複自己!(AKA DRY原則)如果您發現自己在同一個地方複製/粘貼相同的代碼塊,那意味着您做錯了什麼。在這種情況下,你的想法是你有一個循環,並確保你的輸入字段已被清除,你只需複製代碼將其清除到代碼路徑中的3個不同位置。如果您發現需要在整個程序代碼路徑中重複運行相同的代碼,則將其推廣並放入函數中。你的眼睛和下一個人閱讀/維護你的代碼的眼睛會感激它!

  3. 你需要更多的SQL知識/經驗,沒關係,每個人都必須從某個地方開始。在示例中,我刪除了所有選擇的查詢,以支持嘗試ONE插入查詢並根據1查詢的結果分支邏輯。更容易閱讀/維護。此外,標識值應該由您的sql實例處理,而不是在代碼中處理。您通常希望它們按順序使用以避免衝突,並且您不希望它們被最終用戶修改/可見。更正ID列的屬性允許刪除隨機生成代碼。請記住,當您插入帶有標識列的表中時,您不需要在您的INSERT語句中包含標識列(SQL將爲您填充該列)

+0

雖然'Exit Do'是退出循環的合法方式,但我更願意在退出時使用循環條件,而不是強制它。無論如何,OP不需要一個循環來處理他們想要做的事情,而且你給了他一些很好的設計原則。 – Tim

+0

非常真實的蒂姆,我正在更新我的答案來反映這一點。只有真正包括出口blurb,以確保我回答了問題。 –