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

时间:2011-10-29 20:57:32

标签: sql-server ado.net datatable sqlbulkcopy 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);     
}

如果数据表中存在的日期时间值超出了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 个答案:

答案 0 :(得分:3)

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

  

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

因此,SqlBulkCopy将无法处理DateTime2值。相反,我建议使用以下两个选项之一:

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