Как установить тип столбца при использовании SqlBulkCopy для вставки в столбец sql_variant - PullRequest
3 голосов
/ 30 октября 2011

Я использую SqlBulkCopy для вставки / обновления объекта .net DataTable в таблицу SQL Server, которая включает столбец sql_variant. Однако SqlBulkCopy настаивает на хранении значений DateTime, помещенных в этот столбец, в виде sql типа «datetime», когда мне нужно «datetime2».

Моя таблица данных определяется следующим образом:

DataTable dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn("VariantValue", typeof(object))); //this represents my sql_variant column

Затем я добавляю туда некоторые данные, для хранения которых требуется 'datetime2'.

DataRow row = dataTable.NewRow();
row[0] = DateTime.MinValue;
dataTable.Rows.Add(row);

И затем я использую SqlBulkCopy для передачи этих данных на Sql Server:

using (SqlBulkCopy bulk = new SqlBulkCopy(myConnection))
{
     bulk.DestinationTableName = "tblDestination";     
     bulk.WriteToServer(dataTable);     
}

Моя массовая копия потерпит неудачу, если в таблице данных присутствует значение DateTime, выходящее за пределы диапазона типа sql 'datetime' (например, 1/1/0001). Вот почему столбец должен иметь тип datetime2.

Когда вы пишете обычные операторы вставки, которые вставляются в столбец sql_variant, вы можете контролировать тип столбца вариантов, используя CAST или CONVERT. Например:

insert into [tblDestination] (VariantValue) values (CAST('1/1/0001' AS datetime2))

Тогда, если вы хотите отобразить фактический тип столбца варианта, как это:

SELECT SQL_VARIANT_PROPERTY(VariantValue,'BaseType') AS basetype FROM test

Вы увидите, что на самом деле он хранится как «datetime2».

Но я использую SqlBulkCopy, и, насколько я знаю, нет места, чтобы сказать ему, что объекты .net DateTime должны храниться в столбцах типа «datetime2», а не «datetime». В объекте DataTable, о котором я знаю, нет места, чтобы объявить это. Может кто-нибудь помочь мне понять, как этого добиться?

1 Ответ

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

Согласно странице MSDN для SqlBulkCopy (в разделе «Замечания»):

SqlBulkCopy завершится ошибкой при массовой загрузке столбца DataTable типа SqlDateTime в столбец SQL Server, для котороготип является одним из типов даты / времени, добавленных в SQL Server 2008.

Таким образом, SqlBulkCopy не сможет обрабатывать значения DateTime2.Вместо этого я бы предложил один из двух вариантов:

  1. Вставьте каждую строку отдельно (т.е. используйте foreach в вашей DataTable), обрабатывая тип данных там.(Это может помочь использовать сохраненный процесс для обертывания вставки и использовать SqlCommand.Parameters для ввода данных для вставки.)
  2. Массовая вставка во временную таблицу строк, а затем передача данных в основную таблицу.(преобразование типов данных по мере необходимости) в SQL.(что, я думаю, станет излишне сложным, но вы , возможно, сможете получить некоторую производительность для больших наборов данных)
...