2015-10-06 142 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,以确保我回答了问题。 –