使用SqlBulkCopy插入sql_variant列时,如何设置列类型

ado.net datatable sqlbulkcopy sql-server sql-variant

我正在使用SqlBulkCopy从.net DataTable对象插入/更新到包含sql_variant列的SQL Server表。但是,当我需要的是'datetime2'时,SqlBulkCopy坚持将存储在该列中的DateTime值存储为sql类型'datetime'。

我的DataTable定义如下:

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对象上没有任何地方可以声明这一点。任何人都可以帮我弄清楚如何实现这一目标吗?

一般承认的答案

根据SqlBulkCopy的MSDN页面(在“备注”下):

将SqlDateTime类型的DataTable列批量加载到类型为SQL Server 2008中添加的日期/时间类型之一的SQL Server列时,SqlBulkCopy将失败。

因此, SqlBulkCopy将无法处理DateTime2值。相反,我建议两种选择之一:

  1. 单独插入每一行(即在DataTable上使用foreach ),在那里处理数据类型。 (使用存储过程来包装插入并使用SqlCommand.Parameters来键入插入数据可能会有所帮助。)
  2. 批量插入字符串的临时表,然后将数据传输到SQL中的主表(根据需要转换数据类型)。 (我认为这会变得不必要地复杂化,但是你可能能够为大型数据集找到一些性能)



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因