SqlBulkCopy插入标识列

本文关键字:标识 插入 SqlBulkCopy | 更新日期: 2023-09-27 18:01:58

我使用SqlBulkCopy对象将生成的数百万行插入数据库。唯一的问题是我要插入的表有一个标识列。我尝试将SqlBulkCopyOptions设置为SqlBulkCopyOptions.KeepIdentity,并将身份列设置为0, DbNull.Valuenull。这些方法都没有奏效。我觉得我错过了一些很简单的东西,如果有人能启发我,那就太棒了。谢谢!

edit为了澄清,我没有在我导入的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);
}

SqlBulkCopy插入标识列

要让目标表分配标识,不要使用SqlBulkCopyOptions.KeepIdentity选项。相反,从源映射身份,从源提取身份以通过SqlBulkCopy发送。

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

您有两个选择-

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

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

这是表格

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

这就是我如何解决它在。net (dt是你的数据表):

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

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

是的,你是正确的使用SqlBulkCopyOptions.KeepIdentity选项然后bulkcopy作家不认为什么是你的表结构这个对象从开始列写,所以为了我们的需要,我正在做同样的方式来保留我的表中的身份字段,你必须在你的datatable对象中添加一个额外的列与你需要的列,并将空值传递给这个列,然后表自动处理身份。

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

在我的例子中,它原来是列名内的空白,并且在我的SQL表中,我不小心使用了连字符(-)而不是下划线(_)。我用下划线替换了sql表中的空格和连字符,并解决了这个问题。

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

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