Start by fixing the
SQL Injection[
^] vulnerability in your code.
Then, wrap your connection, command and transaction objects in
using
blocks.
Don't try to roll-back the transaction in a
catch
block; the
using
block will take care of that for you if you haven't reached the
Commit
line.
Since you presumably want either all of the rows to be inserted, or none of them, you need to use a single transaction for all rows.
Try something like this:
using (SqlConnection con = new SqlConnection(conn))
using (SqlCommand command = new SqlCommand("INSERT INTO ALQuestion.QuestionMaster(Question, Option1, Option2, Option3, Option4, Answer, LevelID, SkillID, CreatedOn, Status) VALUES (@Question, @Option1, @Option2, @Option3, @Option4, @Answer, @LevelID, @SkillID, @CreatedOn, @Status)", con))
{
con.Open();
using (SqlTransaction transaction = con.BeginTransaction())
{
command.Transaction = transaction;
foreach (DataRow row in ds.Tables[0].Rows)
{
command.Parameters.AddWithValue("@Question", row[0]);
command.Parameters.AddWithValue("@Option1", row[1]);
command.Parameters.AddWithValue("@Option2", row[2]);
command.Parameters.AddWithValue("@Option3", row[3]);
command.Parameters.AddWithValue("@Option4", row[4]);
command.Parameters.AddWithValue("@Answer", row[5]);
command.Parameters.AddWithValue("@LevelID", LevelId);
command.Parameters.AddWithValue("@SkillID", skillid);
command.Parameters.AddWithValue("@CreatedOn", now);
command.Parameters.AddWithValue("@Status", 1);
command.ExecuteNonQuery();
command.Parameters.Clear();
}
transaction.Commit();
}
}
Everything you wanted to know about SQL injection (but were afraid to ask) | Troy Hunt[^]
How can I explain SQL injection without technical jargon? | Information Security Stack Exchange[^]
Query Parameterization Cheat Sheet | OWASP[^]
SQL injection attack mechanics | Pluralsight [^]