我正在尝试使用SqlBulkCopy
批量插入数据到SQL 2008中。
这是我的表:
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
类型。
为什么?我该如何解决这个问题?请帮帮我!
答案 0 :(得分:19)
使用原始表脚本,以下代码可以正常工作。
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列,您需要列映射。
答案 1 :(得分:6)
SQL Date类型与SQL DateTime类型不同。我认为表中的日期列需要是DateTime类型,具体取决于您使用它的方式。
SQL Date Type
SQL DateTime type
更新
我认为Marc的答案应该有效,但您可能需要从源DataTable指定SqlBulkCopyColumnMappings到目标,否则可能会导致映射错误,因为输入表的结构与输出表完全不匹配,即命令交换了日期和行列。
例如
var amount = new SqlBulkCopyColumnMapping("amount", "amount");
var date = new SqlBulkCopyColumnMapping("date", "date");
bulk.ColumnMappings.Add(amount);
bulk.ColumnMappings.Add(date);
答案 2 :(得分:2)
SqlDateTime
代表原始datetime
类型。您是否尝试在DateTime
中使用DataTable
.NET类型?我希望它可以将其转换为TSQL datetime
或date
类型。同上decimal
代替SqlDecimal
。