SqlBulkCopy вычисляемое поле - PullRequest
       3

SqlBulkCopy вычисляемое поле

1 голос
/ 17 февраля 2011

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

К сожалению, я попал в ловушку, мой метод ниже для копирования из Access в SQLServer

public static void BulkCopyAccessToSQLServer
        (string sql, CommandType commandType, DBConnection sqlServerConnection,
            string destinationTable, DBConnection accessConnection, int timeout)
    {
        using (DataTable dt = new DataTable())
        using (OleDbConnection conn = new OleDbConnection(GetConnection(accessConnection)))
        using (OleDbCommand cmd = new OleDbCommand(sql, conn))
        using (OleDbDataAdapter adapter = new OleDbDataAdapter(cmd))
        {
            cmd.CommandType = commandType;
            cmd.Connection.Open();
            adapter.SelectCommand.CommandTimeout = timeout;
            adapter.Fill(dt);

            using (SqlConnection conn2 = new SqlConnection(GetConnection(sqlServerConnection)))
            using (SqlBulkCopy copy = new SqlBulkCopy(conn2))
            {
                conn2.Open();

                copy.DestinationTableName = destinationTable;
                copy.BatchSize = 1000;
                copy.BulkCopyTimeout = timeout;
                copy.WriteToServer(dt);
                copy.NotifyAfter = 1000;
            }
        }
    }

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

Это работало, пока я не достиг таблицы с вычисляемым полем. Похоже, что SQLBulkCopy не знает, как пропустить поле, и пытается обновить столбец, который завершается с ошибкой «Невозможно изменить столбец columnName», поскольку он является вычисляемым столбцом или является результатом оператора объединения. "

Есть ли простой способ пропустить вычисленное поле?

Я надеюсь, что не нужно указывать полное сопоставление столбцов.

1 Ответ

6 голосов
/ 17 февраля 2011

Есть два способа избежать этого:

  • использовать ColumnMappings , чтобы формально определить отношение столбца (вы заметили, что вы этого не хотите)
  • поместите данные в промежуточную таблицу - базовую таблицу, не являющуюся частью ваших основных транзакционных таблиц, вся цель которой - выглядеть точно как этот импорт данных;затем используйте команду TSQL для передачи данных из промежуточной таблицы в реальную таблицу

Я всегда предпочитаю второй вариант по разным причинам:

  • Мне никогда не придетсявозиться с отображениями - это действительно важно для меня; p
  • вставка в реальную таблицу будет полностью зарегистрирована (SqlBulkCopy is not обязательно регистрируется)
  • Iиметь максимально быструю вставку - без проверки ограничений, без индексации и т. д.
  • Я не связываю транзакционную таблицу во время импорта, и нет риска выполнения неповторяющихся запросов к частично импортированной таблице
  • У меня есть опция безопасного прерывания, если импорт завершается неудачей на полпути, без необходимости использовать транзакции (на данный момент ничего не коснулось транзакционной системы)
  • это позволяет некоторый уровень обработки данных, когдавставив его в реальные таблицы, без необходимости либо буферизовать все в DataTable на уровне приложения, либо реализовать пользовательский IDataReader
...