Как поток строк данных в sqlserver? - PullRequest
4 голосов
/ 10 августа 2011

Мне нужно скопировать большой набор результатов из одной базы данных и сохранить его в другой базе данных.

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

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

Данные читаются из исходной таблицы с помощью

var reader = fetchCommand.ExecuteReader();
while (reader.Read()){...}

Есть ли способ вставить эти данные в другой sqlCommand без загрузки всего набора данных в DataTable, но также без вставки строк по одному?

Sqlserver - это MS SQL Server 2008 для обоих источникови целевые базы данных.Базы данных находятся на разных серверах.Использование служб SSIS или связанных серверов недопустимо.

РЕДАКТИРОВАТЬ: По-видимому, можно выполнить потоковую передачу строк в хранимую процедуру с использованием табличных параметров .Также рассмотрим этот подход.

ОБНОВЛЕНИЕ: Да, есть возможность потоковой передачи данных из command.ExecuteReader в другую команду, подобную этой:

var reader = selectCommand.ExecuteReader();
insertCommand.Parameters.Add(
    new SqlParameter("@data", reader)
        {SqlDbType = SqlDbType.Structured}
    );

insertCommand.ExecuteNonQuery();

Где insertCommand является хранимой процедурой с табличным параметром @data.

Ответы [ 2 ]

5 голосов
/ 10 августа 2011

Вам нужно SqlBulkCopy.Вы можете просто использовать его так:

using (var reader = fetchCommand.ExecuteReader())
using (var bulkCopy = new SqlBulkCopy(myOtherDatabaseConnection))
{
  bulkCopy.DestinationTableName = "...";
  bulkCopy.ColumnMappings = ...
  bulkCopy.WriteToServer(reader);
}

Существует также свойство для установки размера партии.Что-то вроде 1000 строк может дать вам лучший компромисс между использованием памяти и скоростью.

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

3 голосов
/ 10 августа 2011

Вы можете использовать SqlBulkCopy со считывателем данных, который делает примерно то, что вы просите (без буферизации и т. Д.) - однако это не будет вызывать хранимые процедуры для вставки.Если вы хотите этого, возможно, используйте SqlBulkCopy, чтобы поместить данные во вторую таблицу (та же структура), затем на сервере БД зациклите строки, вызывающие sproc локально.Таким образом, задержка и т. Д. Перестают быть проблемой (поскольку цикл выполняется на сервере БД).

...