c# - 使用序列设置主 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 值?或者是否可以在表中创建新行之前为序列单独生成多个值?
解决方案
如何通过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
只是一个想法,没有测试。:/
推荐阅读
- c - 关于C中类型的多项选择题,需要有人验证我的答案
- postgresql - 有什么方法可以让 Postgres 在全球范围内自动使用正确的 ISO 8601 时间戳?
- typescript - Ionic 5 中的入职幻灯片
- node.js - 如何在 Heroku 上使用带有 Axios 和 Vue 的 Postgres 数据库?
- git - 我可以在 git 存储库中签出“无”吗?
- java - CORS 允许自定义身份验证过滤器 | 弹簧靴
- lazy-evaluation - 在 QEMU 中禁用延迟评估
- sql-server - 如何按枚举集合值过滤 OData
- laravel - Laravel 刷新页面最多需要 4s 来加载整个 DOM
- flutter - Flutter web 从其所在页面读取cookies