首页 > 解决方案 > 使用序列设置主 ID 时如何将数据批量插入表中

问题描述

我正在尝试使用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 值?或者是否可以在表中创建新行之前为序列单独生成多个值?

标签: c#sqlsql-serverbulkinsertsqlbulkcopy

解决方案


如何通过SqlCommand.ExecuteScalar(). 使用此 SQL 语句作为命令的输入:

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

然后将 column 属性设置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

只是一个想法,没有测试。:/


推荐阅读