SqlBulkCopy
を使用してSQL2008にデータをバッチ挿入しようとしています。
これが私のテーブルです:
IF OBJECT_ID(N'statement', N'U') IS NOT NULL
DROP TABLE [statement]
GO
CREATE TABLE [statement](
[ID] INT IDENTITY(1, 1) NOT NULL,
[date] DATE NOT NULL DEFAULT GETDATE(),
[amount] DECIMAL(14,2) NOT NULL,
CONSTRAINT [PK_statement] PRIMARY KEY CLUSTERED
(
[ID] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
これが私のコードです:
private DataTable GetTable()
{
var list = new List<DataColumn>();
list.Add(new DataColumn("amount", typeof(SqlDecimal)));
list.Add(new DataColumn("date", typeof(SqlDateTime)));
var table = new DataTable("statement");
table.Columns.AddRange(list.ToArray());
var row = table.NewRow();
row["amount"] = (SqlDecimal)myObj.Amount; // decimal Amount { get; set; }
row["date"] = (SqlDateTime)myObj.Date; // DateTime Date { get; set }
table.Rows.Add(row);
return table;
}
private void WriteData()
{
using (var bulk = new SqlBulkCopy(strConnection, SqlBulkCopyOptions.KeepIdentity & SqlBulkCopyOptions.KeepNulls))
{
//table.Columns.ForEach(c => bulk.ColumnMappings.Add(new SqlBulkCopyColumnMapping(c.ColumnName, c.ColumnName)));
bulk.BatchSize = 25;
bulk.DestinationTableName = "statement";
bulk.WriteToServer(GetTable()); // a table from GetTable()
}
}
だから私はエラーが発生しています:
データソースからのタイプ
SqlDateTime
の指定された値は、指定されたターゲット列のタイプdate
に変換できません。
なぜ??どうすれば修正できますか?お願い助けて!
元のテーブルスクリプトを使用すると、次のコードが機能します。
private static DataTable GetTable()
{
var list = new List<DataColumn>();
list.Add(new DataColumn("amount", typeof(Double)));
list.Add(new DataColumn("date", typeof(DateTime)));
var table = new DataTable("statement");
table.Columns.AddRange(list.ToArray());
var row = table.NewRow();
row["amount"] = 1.2d;
row["date"] = DateTime.Now.Date;
table.Rows.Add(row);
return table;
}
private static void WriteData()
{
string strConnection = "Server=(local);Database=ScratchDb;Trusted_Connection=True;";
using (var bulk = new SqlBulkCopy(strConnection, SqlBulkCopyOptions.KeepIdentity & SqlBulkCopyOptions.KeepNulls))
{
bulk.ColumnMappings.Add(new SqlBulkCopyColumnMapping("amount", "amount"));
bulk.ColumnMappings.Add(new SqlBulkCopyColumnMapping("date", "date"));
bulk.BatchSize = 25;
bulk.DestinationTableName = "statement";
bulk.WriteToServer(GetTable());
}
}
Amalがすでに述べたように、Identity列のために列マッピングが必要です。
SQLDate型はSQLDateTime型とは異なります。テーブルの日付列は、使用方法に基づいて、DateTime型である必要があると思います。
更新:
Marcの答えはうまくいくと思いますが、おそらくソースDataTableから宛先へのSqlBulkCopyColumnMappingsを指定する必要があります。そうしないと、入力テーブルの構造が出力テーブルと正確に一致しないため、マッピングが間違っている可能性があります。行の列が入れ替わりました。
例えば
var amount = new SqlBulkCopyColumnMapping("amount", "amount");
var date = new SqlBulkCopyColumnMapping("date", "date");
bulk.ColumnMappings.Add(amount);
bulk.ColumnMappings.Add(date);
SqlDateTime
は、元のdatetime
タイプを表します。 DateTime
でDataTable
.NETタイプを使用してみましたか?これをTSQLのdatetime
またはdate
タイプに変換できることを願っています。同上decimal
の代わりにSqlDecimal
。