Эксель в SQL. Альтернатива массовому копированию?

У меня есть фрагмент кода, который копирует данные из электронной таблицы Excel в таблицу MSSQL, используя DataReader и SqlBulkCopy. Он работал нормально, пока я не создал первичный ключ в таблице, и теперь он не работает. Сначала я удаляю содержимое таблицы SQL, прежде чем снова заполнить ее данными из Excel.

Поскольку я перемещаю лишь небольшой объем данных, мне было интересно, есть ли лучший способ сделать это, чем использование BulkCopy?

Обновление: ниже приведен относительный код, и я получаю сообщение об ошибке: «Заданное значение типа String из источника данных не может быть преобразовано в тип float указанного целевого столбца».

using (OleDbConnection connection = new OleDbConnection(excelConnectionString))
            {
                connection.Open();
                OleDbCommand cmd = new OleDbCommand
                ("SELECT Name, Date, Amount FROM ExcelNamedRange", connection);

                using (OleDbDataReader dr = cmd.ExecuteReader())
                {
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnectionString))
                    {
                        bulkCopy.DestinationTableName = "SqlTable";
                        bulkCopy.WriteToServer(dr);

                    }
                }                 
            }

person Brian    schedule 25.03.2011    source источник
comment
В чем проблема с первичным ключом, какие ошибки вы получаете?   -  person Lasse V. Karlsen    schedule 25.03.2011
comment
@Lasse Я обновил свой пост, указав ошибку и код, который ее вызывает.   -  person Brian    schedule 25.03.2011


Ответы (5)


SqlBulkCopy автоматически сопоставляет поля. Но поскольку вы добавили первичный ключ, это сопоставление по умолчанию больше недействительно.

Вам нужно будет установить ColumnMapping, чтобы явно сообщить вашему объекту SqlBulkCopy, как сопоставлять поля.

Сделайте это для всех своих полей, кроме первичного ключа (при условии, что вы используете идентификатор в ПК).

Например:

_bulkCopyEngine.ColumnMappings.Add("fieldname_from", "fieldname_to");
person Pleun    schedule 25.03.2011

Создание первичного ключа предполагает, что вы применяете ограничение домена (хорошая вещь).

Таким образом, ваша фактическая проблема заключается не в том, что вам нужен другой способ выполнения массовой вставки, но в том, что вам нужно выяснить, почему у вас дублируются ключи (точную причину принудительного ПК).

person Mitch Wheat    schedule 25.03.2011

BulkCopy должен работать нормально, так что проблема, похоже, в дублирующемся ключе (что за сообщение об ошибке?). Либо у вас есть данные, которые неверны, либо созданный вами первичный ключ слишком узкий.

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

GJ

person gjvdkamp    schedule 25.03.2011

хорошо, это, кажется, совсем другая проблема, кажется, в году ExcelNamedRange есть значение, которое нельзя привести к одному из столбцов в SqlTable. Можете ли вы увидеть любой? Может быть, ошибка деления на 0 и т. Д.?

Также убедитесь, что столбцы выровнены. Не уверен точно, как SqlBulkCopy сопоставляет столбцы, я думаю, что он просто помещает первый столбец из NamedRange в первый столбец SqlTale и т. д. Поэтому убедитесь, что они в правильном порядке. (или посмотрите, что произойдет, если вы измените имена)

person gjvdkamp    schedule 25.03.2011

BulkCopy — это самый быстрый способ вставки данных в MSSQL из C#.

person TcKs    schedule 25.03.2011
comment
Меня заставили поверить, что BulkCopy следует использовать только для перемещения больших объемов данных, тогда как я перемещаю только небольшой объем. Или это не так? - person Brian; 25.03.2011
comment
@Brian: Вы можете использовать его для любого объема данных. Однако, если вы знаете, что данные верны, нет причин, почему бы не использовать BulkCopy. Однако у BulkCopy есть несколько особенностей поведения, т. е. никакие триггеры не будут активированы. - person TcKs; 26.03.2011