74

我正在使用该SqlBulkCopy对象将生成的几百万行插入到数据库中。唯一的问题是我要插入的表有一个标识列。我尝试将SqlBulkCopyOptionstoSqlBulkCopyOptions.KeepIdentity和 identity 列设置为0'sDbNull.Valuenull. 这些都没有奏效。我觉得我错过了一些非常简单的东西,如果有人能启发我,那就太好了。谢谢!

编辑为了澄清,我没有在DataTable我正在导入中设置身​​份值。我希望它们作为导入的一部分生成。

编辑 2 这是我用来创建基础SqlBulkCopy对象的代码。

SqlBulkCopy sbc = GetBulkCopy(SqlBulkCopyOptions.KeepIdentity);
sbc.DestinationTableName = LOOKUP_TABLE;

private static SqlBulkCopy GetBulkCopy(SqlBulkCopyOptions options = 
    SqlBulkCopyOptions.Default) 
{
    Configuration cfg = WebConfigurationManager.OpenWebConfiguration("/RSWifi");
    string connString =
    cfg.ConnectionStrings.ConnectionStrings["WifiData"].ConnectionString;
    return new SqlBulkCopy(connString, options);
}
4

9 回答 9

47

要让目标表分配标识,请勿使用该SqlBulkCopyOptions.KeepIdentity选项。相反,不要从源映射身份,也不要从源中提取它以发送到SqlBulkCopy.

于 2011-07-11T14:41:03.543 回答
29

填充对象的ColumnMappingBulkCopy不要映射标识列。标识列将由目标数据库生成。

于 2011-07-11T14:58:37.543 回答
5

你有两个选择——

1 - 使用KeepIdentity并保留源的Identity值。

2 - 不要映射Identity字段。如果您不尝试分配值,目标表将自动分配一个值。

于 2011-07-11T14:43:04.240 回答
2

这就是我在 .NET 中解决它的方法(dt是你的数据表):

dt.Columns.Cast<DataColumn>().ForEach((c, i) => sqlBulkCopy.ColumnMappings.Add(c.ColumnName, i + 1));

Id您基本上通过为目标列分配从 1 而不是 0 开始的序数来跳过标识 ( ) 列。

于 2019-02-13T00:33:53.387 回答
2

这是桌子

CREATE TABLE [dbo].[ProductShippingMethodMap](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ProductId] [int] NOT NULL,
    [ShippingMethodId] [int] NOT NULL,
    [ParentProductId] [int] NOT NULL,
 CONSTRAINT [PK_ProductShippingMethodMap] 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

下面的 C# 代码正在工作

 DataTable dtQtyData = new DataTable();
        dtQtyData.Clear();
        dtQtyData.Columns.Add("Id", typeof(int));

    dtQtyData.Columns.Add("ProductId", typeof(int));
    dtQtyData.Columns.Add("ShippingMethodId", typeof(int));
    dtQtyData.Columns.Add("ParentProductId", typeof(int));


    for (int i = 0; i < ShippingMethodIds.Length; i++)
    {
        for (int j = 0; j < ProductIds.Length; j++)
        {
            var productId = ProductIds[j];
            var shippingMethodId = ShippingMethodIds[i];
            dtQtyData.Rows.Add(new object[] {0,productId, shippingMethodId, parentProductId });
        }

    }
    var connectionString = new DataSettingsManager().LoadSettings().DataConnectionString;
    SqlBulkCopy bulkcopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.Default);
    bulkcopy.DestinationTableName = "ProductShippingMethodMap";
    bulkcopy.WriteToServer(dtQtyData);
于 2019-08-09T10:50:00.947 回答
1

是的,您使用 SqlBulkCopyOptions.KeepIdentity选项是对的,然后批量复制编写器不认为您是什么表结构这个对象从开始列写入,所以为了我们的需要,我正在以同样的方式在我的表中保留身份字段,只是您必须做在您的数据表对象中添加一个额外的列以及您需要的其他列并将空值传递给该列,然后表会自动处理标识。

于 2013-06-26T06:09:17.860 回答
0

使用 JDBC SQLServerBulkCSVFileRecord 结构时,确实需要映射标识列,但忽略标识列中的值。

于 2022-02-22T23:55:26.223 回答
-1

在我的情况下,它原来是列名内的空格,并且在我的 SQL 表中意外使用连字符 (-) 而不是下划线 (_) 的列之一中。我在 sql 表中用下划线替换了空格和连字符,它解决了问题。

于 2016-01-20T15:49:07.910 回答
-2

原因:- 数据末尾的 excel 中有一些空行,可能看起来像空行。批量上传试图将这些空白行上传到表中。

解决方案:- 仅选择包含数据的行 - 将数据复制到新工作表中。假设您在“表 1”中有数据,将其移动到“表 2”并删除“表 1”。

于 2014-09-03T09:46:42.223 回答