4

SqlBulkCopyを使用して、.netDataTableオブジェクトからsql_variant列を含むSQLServerテーブルに挿入/更新しています。ただし、SqlBulkCopyは、必要なものが「datetime2」である場合に、その列に配置された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を使用してそのデータをSQLServerに取り込みます。

using (SqlBulkCopy bulk = new SqlBulkCopy(myConnection))
{
     bulk.DestinationTableName = "tblDestination";     
     bulk.WriteToServer(dataTable);     
}

SQLの「datetime」タイプの範囲外の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を使用しており、私が知る限り、.netDateTimeオブジェクトは「datetime」ではなく「datetime2」タイプの列に格納する必要があることを伝える場所はありません。私が知っているDataTableオブジェクトにも、これを宣言する場所はありません。誰かがこれを実現する方法を理解するのを手伝ってもらえますか?

4

1 に答える 1

3

SqlBulkCopyのMSDNページ(「備考」の下)によると:

タイプがSQLServer2008で追加された日付/時刻タイプの1つであるSQLServer列にタイプSqlDateTimeのDataTable列を一括ロードすると、SqlBulkCopyは失敗します。

したがって、値SqlBulkCopyを処理できなくなりDateTime2ます。代わりに、次の2つのオプションのいずれかをお勧めします。

  1. 各行を個別に挿入し(つまりforeach、DataTableでを使用し)、そこでデータ型を処理します。(ストアドプロシージャを使用して挿入をラップし、挿入のデータを入力するために利用すると役立つ場合がありますSqlCommand.Parameters。)
  2. 文字列の一時テーブルに一括挿入してから、SQLでデータをプライマリテーブルに転送します(必要に応じてデータ型を変換します)。(これは不必要に複雑になると思いますが、大規模なデータセットのパフォーマンスを確認できる場合があります)
于 2011-11-07T19:06:24.610 に答える