问题
I'm using SqlBulkCopy to insert/update from a .net DataTable object to a SQL Server table that includes a sql_variant column. However SqlBulkCopy insists on storing DateTime values put into that column as sql type 'datetime' when what I need is 'datetime2'.
My DataTable is defined like this:
DataTable dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn("VariantValue", typeof(object))); //this represents my sql_variant column
Then I throw some data in there that requires a 'datetime2' to store.
DataRow row = dataTable.NewRow();
row[0] = DateTime.MinValue;
dataTable.Rows.Add(row);
And then I use SqlBulkCopy to get that data into Sql Server:
using (SqlBulkCopy bulk = new SqlBulkCopy(myConnection))
{
bulk.DestinationTableName = "tblDestination";
bulk.WriteToServer(dataTable);
}
My bulk copy will fail if a DateTime value is present in the data table that falls outside the range of the sql 'datetime' type (such as '1/1/0001'). That's why the column needs to be of type 'datetime2'.
When you're writing normal insert statements that insert into a sql_variant column you can control what the type of the variant column is by using CAST or CONVERT. For example:
insert into [tblDestination] (VariantValue) values (CAST('1/1/0001' AS datetime2))
Then if you were to display the actual type of the variant column like this:
SELECT SQL_VARIANT_PROPERTY(VariantValue,'BaseType') AS basetype FROM test
You'd see that indeed it is being stored as a 'datetime2'.
But I'm using SqlBulkCopy and, as far as I know, there's no place to tell it that .net DateTime objects should be stored in columns of type 'datetime2' and not 'datetime'. There's no place on the DataTable object, that I know of, to declare this either. Can anyone help me figure out how to get this to happen?
回答1:
According to the MSDN page for SqlBulkCopy (under "Remarks"):
SqlBulkCopy will fail when bulk loading a DataTable column of type SqlDateTime into a SQL Server column whose type is one of the date/time types added in SQL Server 2008.
So, SqlBulkCopy
won't be able to handle DateTime2
values. Instead, I'd suggest one of two options:
- Insert each row individually (i.e. use a
foreach
on your DataTable), handling the datatype there. (It might help to use a stored proc to wrap the insert and utilizeSqlCommand.Parameters
to type the data for the insert.) - Bulk insert into a temp table of strings, then transfer the data to your primary table (converting data types as necessary) in SQL. (which I think will get unnecessarily complicated, but you may be able to eek out some performance for large datasets)
来源:https://stackoverflow.com/questions/7941661/how-can-i-set-column-type-when-using-sqlbulkcopy-to-insert-into-a-sql-variant-co