簡體   English   中英

SqlBulkCopy 插入標識列

[英]SqlBulkCopy Insert with Identity Column

我正在使用SqlBulkCopy object 將幾百萬生成的行插入到數據庫中。 唯一的問題是我要插入的表有一個標識列。 我嘗試將SqlBulkCopyOptions設置為SqlBulkCopyOptions.KeepIdentity並將標識列設置為0DbNull.Valuenull 這些都沒有用。 我覺得我錯過了一些非常簡單的東西,如果有人能啟發我,那就太好了。 謝謝!

編輯澄清一下,我沒有在我導入的DataTable中設置標識值。 我希望它們作為導入的一部分生成。

編輯 2這是我用來創建基礎SqlBulkCopy object 的代碼。

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

要讓目標表分配標識,請不要使用SqlBulkCopyOptions.KeepIdentity選項。 相反,不要 map 來自源的身份,也不要從源中提取它以發送到SqlBulkCopy

填寫ColumnMapping object 的BulkCopy並且不要 map 標識列。 標識列將由目標數據庫生成。

是的,你是對的,使用SqlBulkCopyOptions.KeepIdentity選項然后批量復制編寫器不認為你是什么表結構這個 object 從開始列寫入,所以為了我們的需要,我正在以同樣的方式在我的表中保留身份字段只是你必須在數據表 object 中創建一個額外的列,其中 rest 是您需要的列,並將 null 值傳遞給該列,然后表會自動處理身份。

這就是我在 .NET Core 中解決它的方法( dt是您的數據表):

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

您基本上通過為目標列分配從 1 而不是 0 開始的序數來跳過身份 ( Id ) 列。

這是桌子

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

你有兩個選擇——

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

2 - 不要 map Identity字段。 如果您不嘗試分配值,目標表將自動分配一個值。

使用 JDBC SQLServerBulkCSVFileRecord 結構時,確實需要映射標識列,但忽略標識列中的值。

原因:- 數據末尾的 excel 中有一些空行,可能看起來像空白行。 批量上傳試圖將這些空白行上傳到表中。

解決方案:- Select 僅包含數據的行 - 將數據復制到新工作表中。 假設您在“表 1”中有數據,將其移動到“表 2”並刪除“表 1”。

在我的情況下,它原來是列名內的空格,並且在我的 SQL 表中意外使用連字符 (-) 而不是下划線 (_) 的列之一中。 我在 sql 表中用下划線替換了空格和連字符,它解決了問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM