Передача данных между DataTable и Sql сервером - PullRequest
2 голосов
/ 19 сентября 2019

У меня есть таблица данных, которая реализована с помощью DataTable.Задача состоит в том, чтобы передать данные каждой ячейки в таблицу Sql Server.Я пытаюсь реализовать это с помощью кода ниже:

Task AddToDB = Task.Run(() =>
{
  for (int i = 0; i < DataTableView.Rows.Count; i++)
  {
    for (int j = 0; j < DataTableView.Columns.Count - 1; j++)
    {

      try
      {
        sqlCommand.CommandText = @"INSERT INTO TestTable  VALUES (@Value1, @Value2, @Value3)";
        sqlCommand.Connection = sqlConnection;
        //sqlCommand.Parameters.AddWithValue("@Value1",  DataTableView.Rows[i][j]);
        sqlCommand.Parameters.AddWithValue("@Value2", DataTableView.Rows[i][j]);
        sqlCommand.Parameters.AddWithValue("@Value3", DataTableView.Rows[i][j]);
        sqlConnection.Open();
        sqlCommand.ExecuteNonQuery();
        sqlConnection.Close();
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.Message, "Error");
      }
    }
  }

});

return AddToDB;

Ошибка в том, что после первой итерации я получаю ошибку: The variable name '@Value1' has already been declared. Variable names must be unique within a query batch or stored procedure.

Я пытался внимательно изучить этот ответ Имя переменной '@' уже объявлено.Имена переменных должны быть уникальными в пакете запроса или хранимой процедуре.в c # и добавить строку

sqlCommand.Parameters.Clear();

, но в конце я получил еще одну ошибку

Cannot insert the value NULL into column 'Value'

Значение переменной обнуляется, а в настройках базы данных оно равноуказано, что значение ячейки не может быть пустым.Как я могу обойти эти ограничения и записать данные в базу данных?

Ответы [ 2 ]

1 голос
/ 19 сентября 2019

Вам необходимо повторно инициализировать sqlCommand.Parameters внутри цикла for.В настоящее время проблема заключается в том, что массив параметров для этой конкретной команды (sqlCommand.Parameters) получает дублированное имя параметра во 2-й итерации, поскольку он все еще имеет предыдущие.

Решения, которое вы связали, должно быть достаточно.Просто очистите параметры непосредственно перед их настройкой:

for (int j = 0; j < DataTableView.Columns.Count - 1; j++)
{

    try
    {
        sqlCommand.CommandText = @"INSERT INTO TestTable  VALUES (@Value1, @Value2, @Value3)";
        sqlCommand.Connection = sqlConnection;

        sqlCommand.Parameters.Clear();
        sqlCommand.Parameters.AddWithValue("@Value1",  DataTableView.Rows[i][j]);
        sqlCommand.Parameters.AddWithValue("@Value2",  DataTableView.Rows[i][j]);
        sqlCommand.Parameters.AddWithValue("@Value3",  DataTableView.Rows[i][j]);

        sqlConnection.Open();
        sqlCommand.ExecuteNonQuery();
        sqlConnection.Close();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error");
    }
}

Также обязательно добавьте имена столбцов TestTable и правильный порядок в операторе INSERT:

sqlCommand.CommandText = @"INSERT INTO TestTable (Column1, Column2, Column3)  VALUES (@Value1, @Value2, @Value3)";
0 голосов
/ 19 сентября 2019

Вызовите AddWithValue только один раз (или, что еще лучше, используйте что-то еще ) вне цикла, затем установите только значение внутри цикла:

cmd.Parameters.AddWithValue("id", -1); //dummy value of same type as ID is
foreach(var ro in table.Rows){
  cmd.Parameters["id"].Value = (int)ro["PersonID"];
  cmd.ExecuteNonQuery();
}

Это упрощенный пример для демонстрациисмысл.Я не рекомендую очищать параметры и повторно добавлять их каждый раз, как об этом говорится в ответе EzLo

На самом деле, вам следует рассмотреть возможность использования DataAdapter, поскольку он уже знает, как это сделать ..

.. и тогда вам, вероятно, следует на самом деле использовать строго типизированные наборы данных и табличные адаптеры для сохранения ваших изменений в базе данных.Когда вы генерируете DataTable строго типа, который связан с таблицей базы данных, он поставляется с выделенным адаптером таблиц, который отвечает за заполнение строк в базе данных и обновление изменений.Цикл чтения, обновления и записи может выглядеть следующим образом:

var ta = new PersonTableAdapter();
var dt = ta.GetDataById(123);
dt.Rows[0].Name = "John Smith";
ta.Update(dt); //it saves the changes to the db; new rows are Inserted, changed rows UPDATEd and removed rows are DELETEd
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...