使用ソフトウェア:Windows 7 64 bit Ultimate、.Net 4、SQL Server 2008 R2。
select @@ version returns:
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1617.0 (X64) Apr 22 2011 19:23:43 Copyright (c) Microsoft Corporation Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)
再現するには、ローカルのSQL Server 2008 R2インスタンスがあると仮定して、linqpadに次のコードを貼り付け、プログラムとして実行します。
それは爆破する:
リンクサーバー '(null)'のOLE DBプロバイダ 'STREAM'が列 '[!BulkInsert] .Value'の無効なデータを返しました。
void Main()
{
SqlConnection cn = new SqlConnection("data source=localhost;Integrated Security=SSPI;initial catalog=tempdb;Connect Timeout=180;");
cn.Open();
IList<decimal> list = new List<decimal>() {-8m, 8m};
decimal result = list.Sum(x => x);
Console.WriteLine(result == 0);
string tableName = "#test";
CreateTemporaryTable(cn, tableName,
String.Format(@"
create table {0} (
Value sql_variant
);
", tableName));
SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(cn);
sqlBulkCopy.DestinationTableName = tableName;
DataTable dt = new DataTable();
dt.Columns.Add("Value", typeof(object));
dt.Rows.Add(result);
sqlBulkCopy.WriteToServer(dt);
sqlBulkCopy.Close();
cn.Close();
}
// Define other methods and classes here
public static void CreateTemporaryTable(SqlConnection cn, string destinationTableName, string createTableStatement)
{
string objectIdValue = (destinationTableName.StartsWith("#") ? "tempdb.." : "") + destinationTableName;
string sql = String.Format(@"
if (object_id (N'{0}', N'U') is not null)
begin
drop table {1};
end;
{2}
", objectIdValue, destinationTableName, createTableStatement);
// Console.WriteLine(sql);
SqlCommand cmd = new SqlCommand(sql, cn);
try
{
cmd.ExecuteNonQuery();
}
finally
{
cmd.Dispose();
}
}
私はおそらくマイクロソフトとのケースを作成するだろうが、誰かがこれを以前に見たかどうか、また回避策があるかどうかを知りたいと思った。すべてのゼロが均等に作られるとは限りません。
ちょうど更新:
私はMicrosoftに事件を開いた。バルク・コピーを介してバリアント列にポンピングされる値の検証をオフにする、不明瞭な文書化されていないdbccフラグを思いつくのに2ヶ月ほどかかりました。このケースは、異なるチーム間でバウンスされた(サポートはインドの民間請負業者によって提供された)、根本的な問題には至っていませんでした。これは、次の行によって生成される価値と、一括コピーコード:
IList<decimal> list = new List<decimal>() {-8m, 8m};
decimal result = list.Sum(x => x);
結論として、それは残念であり、それはまれな出来事であるので、私は諦めました。
Microsoftによって示され、私が使い終わった解決策は、この未記載のフラグDBCC TRACEON(7307、-1)を使用することです。接続レベルまたはサーバーレベルで有効にすることができます。
列 'value'のデータ型が浮動小数点型である場合、おそらく問題はdouble.NaNをSQL Serverに送信することです。これは好きではありません。
double.TryParse( "NaN"、out dv)のような呼び出しは、うれしくtrueを返し、dvをdoubleに設定します.NaN
これが役に立ったら、K.