Пакетное обновление C # для базы данных с использованием хранимой процедуры - PullRequest
3 голосов
/ 30 ноября 2011

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

В настоящее время я реализовал следующее -

foreach (Object obj in customCollection)
{
    string[] updatedValues = GetUpdatedValues(obj.Property1);

    using (SqlConnection sqlConnection = new SqlConnection(connString))
    {
         sqlConnection.Open();

         SqlParameter[] sqlParams = new SqlParameter[2];
         sqlParams[0] = new SqlParameter("@column1", SqlDbType.Float) { Value = updatedValues[0]};
         sqlParams[1] = new SqlParameter("@column2", SqlDbType.Float) { Value = updatedValues[1] };

         using (SqlCommand command = new SqlCommand("upUpdateProcedure", sqlConnection))
         {
              command.CommandType = CommandType.StoredProcedure;
              command.Parameters.AddRange(sqlParams);
              DatabaseHelper.ExecuteNonQuery(command);
         }
    }
}

Итак, как вы видите выше, код вызывает базу данных для каждого объекта в коллекции.

Я просмотрел несколько ссылок для «пакетного обновления с C # на SQL Server», но большинство из этих ссылок предлагали загрузить таблицу внутри кода C #, обновить строки таблицы и затем вызвать DataAdapter.Update ().

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

Пожалуйста, руководство.

Ответы [ 5 ]

3 голосов
/ 30 ноября 2011

Одна вещь, которую я часто делаю, это отправка XML в SQL одним куском.Работает намного лучше, чем вызов DB несколько раз в цикле.

У Джона Галлоуэя есть старое, но вкусное здесь , на которое вы можете ссылаться.сделать это преобразовать ваши данные или столбцы в XML.Если у вас есть эти данные в классе, это действительно просто.Проверьте этот метод расширения - я не помню, где я нашел этот код, поэтому я не смог правильно его приписать.

2 голосов
/ 30 ноября 2011

Если вы используете SQLServer 2008 или более позднюю версию, вы можете заполнить DataTable и передать его хранимой процедуре в качестве параметра с табличным значением.

Информация о табличных параметрах: http://www.sommarskog.se/arrays-in-sql-2008.html#TVP_in_TSQL

Хранимая процедура может получить доступ к параметру таблицы как переменная таблицы, поэтому вы можете выполнить обновление в одном блоке, что хорошо для производительности.

Этот подход аналогичен XML-подходу Билли Кувера, но вместо XML используется DataTable.

0 голосов
/ 30 ноября 2011

Получить DataTable из TableAdapter (генерируется автоматически):

FooTableAdaptor tableAdapter = new FooTableAdapter();
FooDataTable dataTable = FooTableAdaptor.MyQuery(...);

Прокрутка строк DataTable с внесением изменений - это только локально.
Звоните

tableAdapter.Update(dataTable)  

чтобы записать изменение одним ударом.

0 голосов
/ 30 ноября 2011

Да, динамически создавайте SQL-запрос, да, и я знаю, что это плохая производительность по сравнению с хранимой процедурой, но, учитывая все накладные расходы, связанные с открытием и закрытием соединения, которые есть в вашем коде, это может быть не плохой идеей. Я также заметил, что в вашем коде вы пытаетесь открыть и закрыть соединение как можно скорее, это хорошая практика. Тем не менее, я обнаружил, что когда я оставляю 1 соединение открытым для многократного обновления, это ОЧЕНЬ быстрее, чем открытие и закрытие соединения несколько раз. Масштабирование может быть не таким хорошим, потому что вы держите соединение открытым.

0 голосов
/ 30 ноября 2011

Мне кажется, что то, что вы делаете, должно работать нормально.В качестве альтернативы вы можете создать «пакет» обновлений (может быть, 50, 100 или более обновлений каждое) и отправить их все порциями, но не уверены, что это вообще повлияет на производительность и, вероятно, будет менее читабельным.1002 * У вас проблемы с производительностью?Сколько предметов в customCollection?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...