Extract all the code to build the MySqlCommand
from the loop and initialize two parameters, the first one has always the same value, while the second one varies. So, inside the loop check for the empty values in the listview subitem and if not empty, set the value for the second parameter. Now you could execute it and the subsequent loops need to change only the second parameter's value.
string query = "insert into results(sid,c_id)values(@id, @cid))";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.Add("@id", MySqlDbType.Int32).Value = _stuid;
cmd.Parameters.Add("@cid", MySqlDbType.Int32);
conn.Open();
for (int cnt = 0; cnt < lv1.Items.Count; cnt++)
{
string subItem = lv1.Items[cnt].SubItems[2].Text;
if(!string.IsNullOrWhiteSpace(subItem))
{
cmd.Parameters["@cid"].Value = Convert.ToInt32(subItem);
cmd.ExecuteNonQuery();
}
}
conn.Close();
In this way you open the connection just one time and prepare the command before executing the loop. The command uses a parameterized query and thus it is safe from Sql Injection.
Look also at how the sql string, without the quotes and the string concatenation, is more readable.
Final notes:
I am assuming the the c_id
field is a numeric field.
I have changed the for...loop to a simpler form.
This kind of code leads to using a transaction to keep everything atomic (meaning, if one insert fails everything should be rolled back without any change to the database). For more info look at this question