18

我正在尝试使用将数据批量插入到 SQL 2008 中SqlBulkCopy

这是我的桌子:

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() 
    }
}

所以我收到错误:

来自数据源的 type 的给定值SqlDateTime无法转换为date指定目标列的类型。

为什么??我该如何解决?请帮帮我!

4

3 回答 3

23

使用您的原始表格脚本,以下代码有效。

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 列,您需要列映射。

于 2009-06-21T19:53:08.780 回答
7

SQL Date 类型不同于 SQL DateTime 类型。我认为表中的日期列需要是 DateTime 类型,具体取决于您使用它的方式。

SQL 日期类型
SQL 日期时间类型

更新:

我认为 Marc 的答案应该有效,但您可能需要指定从源 DataTable 到目标的 SqlBulkCopyColumnMappings,否则可能会出现映射错误,因为输入表的结构与输出表不完全匹配,即日期顺序和行列交换。

例如

var amount = new SqlBulkCopyColumnMapping("amount", "amount");
var date = new SqlBulkCopyColumnMapping("date", "date");
bulk.ColumnMappings.Add(amount);
bulk.ColumnMappings.Add(date);
于 2009-06-21T14:29:05.553 回答
2

SqlDateTime代表原始datetime类型。您是否尝试过仅在DateTime.NET 中使用 .NET 类型DataTable?我希望它可以将其转换为 TSQLdatetimedate类型。同上decimal而不是SqlDecimal.

于 2009-06-21T14:29:06.817 回答