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

时间:2015-12-17 18:26:40

标签: c# sql

我是SQL和C#的新手。 screenshot

如截图所示,我想通过仅插入来自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行?谢谢

2 个答案:

答案 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();
       }
   }
}