Each survey has multiple questions (10) and each question has it’s own rating. At the moment I can only insert a rating for each question one at a time. I’m trying to create one form so that I can add a rating to each question at the same time.
The issue I’m running into is that the form only enters the rating for the first question and runs into an error at the second instance of: ‘throw new ApplicationException(“Data error.”);’
Each question needs to keep the selected survey ID to identify which survey it belongs to.
===== Code Behind =====
protected void AddRatingBTN_Click(object sender, EventArgs e)
{
if (DropDownListSurvey.SelectedValue == "Select")
{
//Label1.Text = "hi";
return;
}
string connectionString = WebConfigurationManager.ConnectionStrings["DBConnectionString1"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("InsertRating", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@Rating_ID", SqlDbType.Int, 7));
cmd.Parameters["@Rating_ID"].Direction = ParameterDirection.Output;
cmd.Parameters.Add(new SqlParameter("@Question_ID", SqlDbType.Int));
cmd.Parameters["@Question_ID"].Value = 1000;
cmd.Parameters.Add(new SqlParameter("@Survey_ID", SqlDbType.Int));
cmd.Parameters["@Survey_ID"].Value = Convert.ToInt32(DropDownListSurvey.SelectedValue.ToString());
cmd.Parameters.Add(new SqlParameter("@Score", SqlDbType.Char, 5));
cmd.Parameters["@Score"].Value = Question_1.Text;
try
{
con.Open();
cmd.ExecuteNonQuery();
// txtRating_ID.Text = Convert.ToString(cmd.Parameters["@Rating_ID"].Value);
}
catch (SqlException err)
{
// Replace the error with something less specific.
// You could also log the error now.
throw new ApplicationException("Data error.");
}
finally
{
con.Close();
}
cmd.Parameters.Add(new SqlParameter("@Rating_ID", SqlDbType.Int, 7));
cmd.Parameters["@Rating_ID"].Direction = ParameterDirection.Output;
cmd.Parameters.Add(new SqlParameter("@Question_ID", SqlDbType.Int));
cmd.Parameters["@Question_ID"].Value = 1001;
cmd.Parameters.Add(new SqlParameter("@Score", SqlDbType.Char, 5));
cmd.Parameters["@Score"].Value = Question_2.Text;
try
{
con.Open();
cmd.ExecuteNonQuery();
// txtRating_ID.Text = Convert.ToString(cmd.Parameters["@Rating_ID"].Value);
}
catch (SqlException err)
{
// Replace the error with something less specific.
// You could also log the error now.
throw new ApplicationException("Data error.");
}
finally
{
con.Close();
}
cmd.Parameters.Add(new SqlParameter("@Rating_ID", SqlDbType.Int, 7));
cmd.Parameters["@Rating_ID"].Direction = ParameterDirection.Output;
cmd.Parameters.Add(new SqlParameter("@Question_ID", SqlDbType.Int));
cmd.Parameters["@Question_ID"].Value = 1002;
cmd.Parameters.Add(new SqlParameter("@Score", SqlDbType.Char, 5));
cmd.Parameters["@Score"].Value = Question_3.Text;
try
{
con.Open();
cmd.ExecuteNonQuery();
// txtRating_ID.Text = Convert.ToString(cmd.Parameters["@Rating_ID"].Value);
}
catch (SqlException err)
{
// Replace the error with something less specific.
// You could also log the error now.
throw new ApplicationException("Data error.");
}
finally
{
Response.Redirect(Request.RawUrl);
con.Close();
}
}
}
}
This code brings back some old memories, not really great ones unfortunately. Anyway, I think the problem is that you’re adding the parameters multiple times to the same command object. Your first execute works because you have the correct number of parameters. In the prep for the second run, you’re adding them again, but the cmd still has the old parameters still there. If you remove the .Add calls after the first time it should work.
You should look into more modern ways of handling data access. Check out LINQ-to-SQL at the very least.
I’ll also add a few design pointers. Based on the data you’re saving, you probably want to have the inserts wrapped in a single transaction, which is pretty simple. You should also avoid closing and reopening the connection between statements (which won’t be possible in a useful transaction anyway). You only need to open the connection on the first call, and close after the last. Last, you should put the last close before the Redirect because Redirect(string) will abort the thread.