NULL可能な列が含まれている場合、SqlBulkCopyを使用して問題が発生します。 SqlBulkCopyはnull許容列を処理する方法を知らず、長さがゼロの列が見つかると不正なサイズのエラーがスローされるようです。エラーは、 「bcpクライアントから無効な列長を受け取りました...」です。
私はこれに対処するベストプラクティスが何であるか疑問に思っています。 これは、この問題を説明する良いフォーラム投稿、およびCSVファイルを読むためにそれを解決する方法のようです。
私の状況は、典型的でシンプルなものだと思います。 1つのデータベーステーブルから別のデータベースに未知数のデータを移動する必要があります。 SSIS / DTSまたはSQL Serverのリンクサーバーを使用する方が簡単ですが、顧客はデータの移動をアプリに要求します。
nullまたはnullのフィールドを使用してデータを移動するためのこれ以上の改良されたソリューション
//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 );
SqlBulkCopyクラスはnullフィールドに対応できません。フィールドの長さを計算しようとする前に、フィールドがヌルかどうかをチェックしません。したがって、エラーを投げる。
質問に引用された投稿は、null値ではなくDBNull.ValueをスローするIDataReaderの実装を参照しています。これはSqlBulkCopyの不具合を回避します。
null許容値をチェックすると、多くの問題が解決されます。しかし、データベースではnullにできないDateTime値でまだ問題がありました。私のソースはCSVなので、値がnullになる可能性があります。 C#の日付と時刻の最小値とSQLの最小値が異なるため、DateTime.MinValueにnull値を設定しても解決策にはなりませんでした。
宛先列をDateTime2に設定することにより、DateTime列に関するすべての問題が解決されました。その他の列(int eg)は問題なくnullにすることができます。