如何使用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(); } } }
- 如果sqlexpress位于安装了SQLSERVER2008的同一台机器上,则SmoApplication.EnumAvailableSqlServers()不会列出默认实例
- 来自数据库的ASP.NET MVC下拉列表
- 如何使用Owin中间件拦截404
- 对于C#中byte 类型的键,为什么Hashtable不会为“ContainsKey”返回true?
- 如何将DateTimeKind.Unspecified类型的DateTime转换为C#(.NET)中的DateTime.Kind.Utc
- 为什么我的Azure WebJobs“settings.job”文件被忽略?
- 如何使用Selenium将关键和弦发送到文本区域?
- MVVM c#如何将异步数据加载到属性中?
- 在LINQ中检查年龄filter的最短方法?