如何使用SQL查询更新表中的多个行?

我是SQL和C#的新手。 截图

如屏幕截图所示,我想通过仅插入DataGridView2 Qty,Description和Price值来更新Order Details表中的3行(#3号订单)。 我使用Order_Number和DateTime的组合使订单详细信息独特且易于在表格中找到。

我使用了以下代码,但它根据DataGridView2中的第0行更新了3行#3顺序:

 private void Update_OrderDetails_Click(object sender, EventArgs e) { SqlConnection cn = new SqlConnection("Data Source=PCNmm-TOSH;Initial Catalog=mydb;Integrated Security=True"); cn.Open(); SqlCommand cm = new SqlCommand("UPDATE Customer_Order_Details SET Qty = @Qty, Description = @Description, Price = @Price WHERE Order_Number = @OrderNumber and DateTime = @DateTime "); cm.Parameters.Add("@OrderNumber", SqlDbType.Int); cm.Parameters["@OrderNumber"].Value = 3; cm.Parameters.Add("@DateTime", SqlDbType.DateTime); cm.Parameters["@DateTime"].Value = "2015 - 12 - 17 15:04:57.043"; cm.Parameters.Add("@Qty", SqlDbType.Int); cm.Parameters["@Qty"].Value = dataGridView2.Rows[0].Cells[2].Value; cm.Parameters.Add("@Description", SqlDbType.Text); cm.Parameters["@Description"].Value = dataGridView2.Rows[0].Cells[3].Value; cm.Parameters.Add("@Price", SqlDbType.Money); cm.Parameters["@Price"].Value = dataGridView2.Rows[0].Cells[4].Value; cm.Connection = cn; cm.ExecuteNonQuery(); } } 

但是,如果我使用for语句for (i = 0; i <= dataGridView2.RowCount; i++)并使用dataGridView2.Rows[i].Cells[Cell_Number].Value 。参数中的值。它给出了错误“参数化查询”(@ OrderNumber int,@ DateTime datetime,@ Qty int,@ Description text,’期望参数’@Qty’,未提供“

我想要的是:

订单详细信息表中的Row 1 DataGridView2 Row 0 = DataGridView2 Row 0

订单详细信息表中的Row 2 DataGridView2 Row 1 = DataGridView2 Row 1

订单详细信息表中的Row 3 DataGridView2 Row 2 = DataGridView2 Row 2

但问题是:我不知道如何在Database中的OrderDetail表中索引这3行。 任何想法如何更新数据库订单明细表中的3行(订单3)与DataGridView2中的3行? 谢谢

 private void Update_OrderDetails_Click(object sender, EventArgs e) { string sql = @"insert Customer_Order_Details (Order_Number, DateTime, Qty, Description, Price) values (@OrderNumber, @DateTime@Qty, @Qty, @Description, @Price)"; using (SqlConnection cn = new SqlConnection("Data Source=.;Initial Catalog=mydb;Integrated Security=True")) using (SqlCommand cm = new SqlCommand(sql, cn)) using (SqlCommand delete = new SqlCommand("delete from Customer_Order_Details where Order_Number = @OrderNumber")) { cm.Parameters.AddWithValue("@OrderNumber", 3); cm.Parameters.AddWithValue("@DateTime", new DateTime(2015, 12, 17, 15, 4, 57, 43)); cm.Parameters.AddWithValue("@Qty", 0); cm.Parameters.AddWithValue("@Description", ""); cm.Parameters.AddWithValue("@Price", 0M); delete.Parameters.AddWithValue("@OrderNumber", 3); cn.Open(); delete.ExecuteNonQuery(); foreach (DataGridViewRow row in dataGridView2.Rows) { cm.Parameters["@Qty"].Value = row.Cells[2].Value; cm.Parameters["@Description"].Value = row.Cells[3].Value; cm.Parameters["@Price"].Value = row.Cells[4].Value; cm.ExecuteNonQuery(); } cn.Close(); } } 

PS:代码只是一个示例。 使用order_number,datetime作为唯一值是一个可怕的想法(它不是唯一的,这是另一个问题。即使它是,这是一个可怕的想法)。 代码使用delete + insert,因为你实际上没有主键来使用更新(再次,一个糟糕的表设计)。

DateTime和Order_Number字段不足以形成唯一键,因此当您在WHERE子句中使用这些参数调用UPDATE时,最后使用Ordernumber和DateTime以相同的参数值更新每个记录。
您需要一个或多个字段作为主键或唯一键才能在where语句中使用。 (某些标识列用于引用记录并且从未向您的客户显示)

如果这不是一个选项,则可以删除先前的数据并使用INSERT查询再次添加它们。
这不是推荐的做法,但如果您在此表上没有主键,则可能是唯一可行的解​​决方案。

无论如何,这应该在事务块中完成,以避免在出现问题时丢失数据

 private void Update_OrderDetails_Click(object sender, EventArgs e) { string cmdText = @"INSERT INT Customer_Order_Details (Order_Number, DataTime, Qty, Description, Price) VALUES(@Order_Number, @DateTime, @Qty, @Description, @Price)"; // Put every disposable objects inside a using block using(SqlConnection cn = new SqlConnection(....)) { cn.Open(); using(SqlTransaction tr = cn.BeginTransaction()) // Start the transaction using(SqlCommand cm = new SqlCommand("", cn)); { // Delete the data that you are ready to reinsert cm.CommandText = @"DELETE FROM Customer_Order_Details WHERE Order_Number = @OrderNumber AND DateTime = @DateTime"; cm.Parameters.Add("@OrderNumber", SqlDbType.Int).Value = 3; cm.Parameters.Add("@DateTime", SqlDbType.DateTime).Value = "2015 - 12 - 17 15:04:57.043"; cm.ExecuteNonQuery(); // Change the commandtext, leave the parameters already there and // add the parameters required for insert, DO NOT PUT VALUES NOW cm.CommandText = cmdCommandText; cm.Parameters.Add("@Qty", SqlDbType.Int).Value = 0; cm.Parameters.Add("@Description", SqlDbType.Text).Value = ""; cm.Parameters.Add("@Price", SqlDbType.Money).Value = 0; // Loop on your rows and reinsert the records for(int rowIndex = 0; x < 3; rowIndex++) { cm.Parameters["@Qty"].Value = dataGridView2.Rows[rowIndex].Cells[2].Value; cm.Parameters["@Description"].Value = dataGridView2.Rows[rowIndex].Cells[3].Value; cm.Parameters["@Price"].Value = dataGridView2.Rows[rowIndex].Cells[4].Value; cm.ExecuteNonQuery(); } tr.Commit(); } } }