如何使用可空列的SqlBulkCopy

时间:2009-10-23 17:25:14

标签: sql sql-server nullable sqlbulkcopy

当涉及可空列时,我遇到使用SqlBulkCopy的问题。听起来像SqlBulkCopy不知道如何处理可空列并在遇到零长度列时抛出非法大小错误。错误是“从bcp客户端收到无效的列长度...”

我想知道处理这个问题的最佳做法是什么。 This似乎是一个很好的论坛帖子,描述了这个问题以及如何解决它来阅读csv文件。

我认为我的情况非常简单。我需要将一个未知的数据从一个数据库表移动到另一个数据库。对我来说更简单的答案是在sql server中使用SSIS / DTS或链接服务器,但是客户希望应用程序进行数据移动。

对于使用可空字段移动数据的这个或更好的流媒体解决方案是否有一个已知的工作?

//access db
string src_db = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\SourceDB.mdb;Jet OLEDB ";
//sql db
string dest_db = @"Data Source=.\TEST;Initial Catalog=testdb;User Id=user;Password=password;";
string sql = "";
OleDbConnection sdb = new OleDbConnection( src_db );
OleDbCommand cmd = new OleDbCommand( sql, sdb );
OleDbDataReader rs = null;

SqlConnection db = new SqlConnection( dest_db );
SqlCommand clear = null;
SqlBulkCopy bulk_load = null;

// Read in the source table
sql = "select * from someTable";
sdb.Open();
cmd = new OleDbCommand( sql, sdb );
rs = cmd.ExecuteReader();

// Import into the destination table
bulk_load = new SqlBulkCopy( db );
bulk_load.DestinationTableName = "test";
bulk_load.WriteToServer( rs );

3 个答案:

答案 0 :(得分:5)

SqlBulkCopy类无法处理空字段。在尝试计算字段长度之前,它不会检查字段是否为空。因此抛出一个错误。

我在问题中引用的帖子引用了IDataReader的实现,该实现抛出了DBNull.Value而不仅仅是null值 - 这可以解决SqlBulkCopy中的缺陷。

答案 1 :(得分:0)

如果您在目标字段中检查了可空字段,它应该可以正常工作。

答案 2 :(得分:0)

检查可空值将解决很多问题。但是我仍然在使用DateTime值时遇到麻烦,该值在数据库中不能为null。我的来源是CSV,因此值可以为null。将空值设置为DateTime.MinValue不是解决方案,因为C#datetime最小值和Sql最小值之间存在差异。

通过将目标列设置为DateTime2,解决了DateTime列的所有问题。其他列(例如int)可以为null,没有问题。