sequence不能自动替代identity,因其是数据库级对象,需显式调用next value for才能获取值,不具列级自动填充能力;identity则是表列属性,insert时自动赋值。

SEQUENCE 不能直接替代 IDENTITY,它生成的是独立于表的整数序列,必须显式调用 NEXT VALUE FOR 才能获取值,且不自动绑定到 INSERT。
为什么不能像 IDENTITY 那样自动填充?
IDENTITY 是列级属性,SQL Server 在 INSERT 时自动计算并填入;而 SEQUENCE 是数据库级对象,和任何表都无物理关联。你得手动把它“塞”进 INSERT 语句里,否则字段为空或报错(如果该列是 NOT NULL)。
-
NEXT VALUE FOR必须出现在 VALUES 列表、子查询或 DEFAULT 约束中,不能放在 WHERE 或 GROUP BY 里 - 同一语句中多次调用
NEXT VALUE FOR seq_name会返回递增的不同值,不是重复取同一个 - 如果事务回滚,已取出的 sequence 值不会归还——这是设计行为,不是 bug
最常用写法:在 INSERT ... VALUES 中直接调用
适用于单行或少量多行插入,语义清晰,不易出错。
INSERT INTO orders (order_id, customer_name, amount)
VALUES (NEXT VALUE FOR dbo.seq_order_id, 'Alice', 129.50),
(NEXT VALUE FOR dbo.seq_order_id, 'Bob', 87.20);
注意:NEXT VALUE FOR 每次调用都推进序列,哪怕某一行因约束失败插入失败,该值也已消耗。
- 不要在循环里反复执行
SELECT NEXT VALUE FOR ...再拼 INSERT——性能差且易并发冲突 - 若需批量插入且希望用同一组连续 ID,应先用
sp_sequence_get_range预取一段值 - 避免在视图或函数中隐式调用 sequence,可能导致不可预期的值跳变
用 DEFAULT 约束简化 INSERT 语法
把 sequence 绑定到列默认值后,INSERT 可省略该字段,更接近 IDENTITY 的体验:
ALTER TABLE orders ADD CONSTRAINT DF_orders_order_id DEFAULT (NEXT VALUE FOR dbo.seq_order_id) FOR order_id;
之后可写:
INSERT INTO orders (customer_name, amount) VALUES ('Charlie', 210.00);
但要注意:
- DEFAULT 只在字段未显式提供值时生效;一旦你在 INSERT 中写了
order_id = ...,就绕过 default - 无法对已有数据批量补 default 值,
ALTER COLUMN ... ADD DEFAULT不影响历史行 - 若表有多个 identity-like 列,sequence 默认值无法像 IDENTITY 那样保证“每行只取一个值”的语义原子性
并发场景下 sequence 值可能不连续
SEQUENCE 本身不锁整张表,高并发下多个会话同时取值,中间可能被跳过(比如某个事务取了值但没提交就断开)。这不是缺陷,而是为性能做的权衡。
- 如果你需要严格连续编号(如发票号),sequence 不适合,得用带应用层协调的方案或临时表+MAX()+1
- 设置
NO CACHE可减少跳号(每次取值都刷盘),但严重拖慢性能,仅调试用 - 缓存大小(CACHE 10 / CACHE 1000)影响跳号概率和吞吐量,生产环境建议至少 CACHE 50
真正麻烦的不是跳号,而是误以为 sequence 能替代 identity 后,在迁移旧逻辑时漏掉显式调用,导致 NOT NULL 列插入失败——这个错误往往在测试环境不暴露,上线才炸。










