簡體   English   中英

主ID設置有序列時如何批量插入數據到表中

[英]How to bulk insert data into a table when the primary ID is set with a sequence

我正在嘗試使用SqlBulkCopy將多行插入到其中 Id 列設置有序列的表中。 序列和表格如下所示:

CREATE SEQUENCE [dbo].[MyTableId] 
 AS [int]
 START WITH 1
 INCREMENT BY 1
 MINVALUE -2147483648
 MAXVALUE 2147483647
 CACHE  10 
GO

CREATE TABLE [dbo].[MyTable](
    [Id] [int] NOT NULL,
    [SomeColumn] [int] NOT NULL,
    [AnotherColumn] [nvarchar](100) NOT NULL
  CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED 
  (
    [Id] ASC
  )
GO

ALTER TABLE [dbo].[MyTable] ADD
  CONSTRAINT [DF_MyTable_Id]
  DEFAULT (NEXT VALUE FOR [MyTableId]) FOR [Id]
GO

導入行的代碼如下所示:

var table = new DataTable();

using (var adapter = new SqlDataAdapter($"SELECT TOP 0 * FROM dbo.MyTable", conn))
{
    adapter.Fill(table);
}

foreach (Data d in data)
{
    var row = table.NewRow();

    row["SomeColumn"] = d.someColumnValue;
    row["AnotherColumn"] = d.anotherColumnValue;

    table.Rows.Add(row);
}

using (var bulk = new SqlBulkCopy(conn))
{
    bulk.DestinationTableName = "dbo.MyTable";
    bulk.WriteToServer(table);
}

將數據寫入服務器時會失敗,因為

System.InvalidOperationException: 'Column 'Id' does not allow DBNull.Value.'

我曾嘗試從表定義中刪除 Id 列,但這只會將列序數減一。 我試過將 Id 行設置為:

table.Columns["Id"].AutoIncrement = true;

但這會忽略序列,並在重復運行導入時,從 0 重新啟動自動增量值。

我將如何指示服務器使用其序列生成新的 Id 值? 或者是否可以在表中創建新行之前分別為序列生成多個值?

如何通過SqlCommand.ExecuteScalar()向 SQL Server 詢問當前序列值。 使用此 SQL 語句作為命令的輸入:

SELECT current_value
FROM sys.sequences
WHERE OBJECT_ID = OBJECT_ID(N'dbo.MyTableId');

然后將列屬性AutoIncrementSeed設置為前一個值加一:

// ... code to get current sequence value
string sqlText = <above sql goes here>;
SqlCommand getSeqValue = new(sqlText, your_connection);
long currentSequenceValue = (long)getSeqValue.ExecuteScalar();

// Construct DataTable structure
// maybe replacing adapter.Fill(table);  
// with 
//adapter.FillSchema(table,SchemaType.Source);

// tell table to start ID on current sequence value + 1 (or AutoIncrementStep)
table.Columns["Id"].AutoIncrement = true;
table.Columns["Id"].AutoIncrementSeed = currentSequenceValue + 1;

// prepare things and bulk insert

只是一個想法,還沒有測試。 :/

暫無
暫無

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

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