如截图所示,我想通过仅插入来自DataGridView2
的数量,描述和价格值来更新订单明细表中的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
它给了我错误&#34;参数化查询&#39;(@ OrderNumber int,@ DateTime datetime,@ Qty int,@ Description text,&#39;期望参数&#39; @Qty&#39;,没有提供&#34;
我想要的是:
订单明细表=Row 1
中的 DataGridView2 Row 0
订单明细表= Row 2
DataGridView2 Row 1
订单明细表= Row 3
DataGridView2 Row 2
但问题是:我不知道如何在Database中的OrderDetail表中索引这3行。 任何想法如何更新数据库订单明细表中的3行(订单3)与DataGridView2中的3行?谢谢
答案 0 :(得分:3)
div
PS:代码只是一个示例。使用order_number,datetime作为唯一值是一个可怕的想法(它不是唯一的,这是另一个问题。即使它是,这是一个可怕的想法)。代码使用delete + insert,因为您实际上没有主键可以使用更新(再次,一个糟糕的表设计)。
答案 1 :(得分:2)
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();
}
}
}