使用 SqlBulkCopy 插入数据时出错

发布于 2024-07-25 22:05:08 字数 1683 浏览 2 评论 0原文

我正在尝试使用 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 类型。

为什么?? 我该如何解决这个问题? 请帮帮我!

I'm trying to batch insert data into SQL 2008 using SqlBulkCopy.

Here is my table:

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

Here is my code:

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

So I'm getting error:

The given value of type SqlDateTime from the data source cannot be converted to type date of the specified target column.

Why?? How can I fix that? Help me, please!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我家小可爱 2024-08-01 22:05:08

使用原始表脚本,以下代码可以工作。

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

Using your original table script, the following code works.

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

As already stated by Amal, you need the column mappings because of the Identity column.

铁憨憨 2024-08-01 22:05:08

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

SQL 日期类型

SQL DateTime type

更新:

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

例如

var amount = new SqlBulkCopyColumnMapping("amount", "amount");
var date = new SqlBulkCopyColumnMapping("date", "date");
bulk.ColumnMappings.Add(amount);
bulk.ColumnMappings.Add(date);

The SQL Date type is different to the SQL DateTime type. I think the date column in your table needs to be of type DateTime, based on the way you are using it.

SQL Date Type

SQL DateTime type

Update:

I think Marc's answer should work, but you probably need to specify the SqlBulkCopyColumnMappings from your source DataTable to the destination, otherwise it might be getting the mapping wrong because the structure of your input table does not match the output table exactly ie order of date and row columns swapped.

eg

var amount = new SqlBulkCopyColumnMapping("amount", "amount");
var date = new SqlBulkCopyColumnMapping("date", "date");
bulk.ColumnMappings.Add(amount);
bulk.ColumnMappings.Add(date);
枕头说它不想醒 2024-08-01 22:05:08

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

SqlDateTime represents the original datetime type. Have you tried just using the DateTime .NET type in the DataTable? I would hope that it can convert this to either the TSQL datetime or date types. Ditto decimal instead of SqlDecimal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文