如何在可空列中使用SqlBulkCopy

3
我在使用SqlBulkCopy时遇到了问题,涉及到可为空的列。听起来SqlBulkCopy不知道如何处理可为空的列,并且在遇到长度为零的列时会抛出非法大小错误。错误信息为“从bcp客户端接收到无效的列长度...”。
我想知道处理这个问题的最佳实践是什么。这篇论坛帖子似乎描述了这个问题以及如何解决它以读取csv文件。
我认为我的情况相当典型和简单。我需要将未知数量的数据从一个数据库表移动到另一个数据库。对于我来说,更简单的答案是使用SSIS/DTS或SQL Server中的链接服务器,但客户希望应用程序进行数据移动。
是否有已知的解决方案或更好的流式解决方案,以移动具有可为空字段的数据?
//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个回答

6

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

我在问题中引用的帖子引用了一个实现IDataReader的方法,该方法会抛出DBNull.Value而不仅仅是null值——这可以解决与SqlBulkCopy相关的缺陷。


0

检查可空值可以解决很多问题。但是我仍然遇到了DateTime值的问题,因为它们在数据库中不能为null。我的数据源是CSV文件,所以值可以为空。将null值设置为DateTime.MinValue不是解决方案,因为C# datetime最小值和Sql最小值之间存在差异。

通过将目标列设置为DateTime2,所有与DateTime列相关的问题都得到了解决。其他列(例如int)可以随意为空而没有问题。


0

如果你在目标字段中勾选了可空性,它应该可以正常工作。


数据库中的列被标记为可空。上面是在该表上执行的代码。 - Chad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接