2015-12-17 2 views
2

Я новичок в SQL и C#. screenshotКак обновить несколько строк в таблице с помощью SQL-запроса?

Как показано на скриншоте, я хочу, чтобы обновить 3 строки (заказ # 3) в таблице Сведения о заказе, вставив только Кол-во, описание и стоимость значений из DataGridView2. Я использую комбинацию Order_Number и DateTime, чтобы сделать детали заказа уникальными и легко найти в таблице.

Я использовал следующий код, но он обновляет 3 строки порядка № 3, основанные на строке 0 в DataGridView2:

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', который не был снабжен"

что я хочу:

Row 1 в деталях заказа таблицы = DataGridView2 Row 0

Row 2 в деталях заказа таблицы = DataGridView2 Row 1

Row 3 в деталях заказа таблицы = DataGridView2 Row 2

Но проблема: я не знаю, как индексировать эти 3 строки в таблицу OrderDetail в базе данных. Любая идея, как я могу обновить 3 строки (заказ 3) в таблице данных заказа базы данных с 3 строками в DataGridView2? Thank you

+0

'Cells [Cell_Number]' what is cell_number? –

+2

Дата и номер заказа недостаточно для создания уникального ключа, поэтому, что бы вы ни делали, вы закончите обновлять каждый номер заказа = 3 и предлагаемую дату с теми же значениями.Вам нужно поле (или поля), которое действует как первичный ключ или уникальный ключ для использования в вашем заявлении. – Steve

+0

Вам нужно либо отслеживать, что изменилось в сетке, прежде чем пользователь нажал кнопку обновления, либо просто обновил заказ _every_ от сетью, даже если она не изменилась. Хотя проще вы можете столкнуться с проблемами, если одновременно несколько клиентов обновляют разные заказы. – Tony

ответ

2
private void Update_OrderDetails_Click(object sender, EventArgs e) 
{ 
    string sql = @"insert Customer_Order_Details 
     (Order_Number, DateTime, Qty, Description, Price) 
     values 
     (@OrderNumber, @[email protected], @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, потому что у вас на самом деле нет первичных ключей для использования обновления (опять же, ужасный дизайн таблицы).

+0

@ Цетин Базос. Благодарим вас за отзывы и помощь. как я уже сказал, я новичок в C#, и да, я думаю, что мой стол был разработан не очень хорошо. Это потому, что я не знал, как сохранить номер заказа с использованием первичного ключа, поэтому я использовал только одну таблицу, в которой хранятся все данные о заказе клиента, и когда я пытался обновить данные заказа, эта проблема возникла, как я объяснил в своем вопросе. есть ли у вас быстрый план переделать эту таблицу? спасибо – naouf

+0

Добавить первичный ключ. –

2

Поля DateTime и Order_Number не достаточны для создания уникального ключа, поэтому при вызове UPDATE с этими параметрами в предложении WHERE заканчивается обновление каждой записи с номером 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(); 
     } 
    } 
} 
+0

, прежде чем я разместил свой вопрос, я думал удалить данные и снова вставить их после изменения, как вы упомянули, но я оставил эту идею в качестве крайней меры, потому что это звучало не очень хорошо. Как вы сказали, я создам новый столбец, действующий как уникальный, чтобы идентифицировать эти 3 строки или, возможно, я буду использовать идею удаления. Спасибо – naouf

Смежные вопросы