首页 > 解决方案 > Oracle 序列生成器中的保留编号

问题描述

在使用 Oracle 序列生成器生成新数字时,我们需要跳过几个定义的数字。

例如:- 我们定义的范围为 0001-9999,但在此范围内,Oracle 排序器永远不会生成数字 0011、0020、2056、6547。

有可能吗?

标签: oracleoracle11gsequence

解决方案


您不能仅在内置序列机制中做到这一点。作为一种解决方法,您可以有一个跳过禁止值的包装函数,例如:

CREATE FUNCTION get_seq RETURN NUMBER IS
  seq_val PLS_INTEGER := 11; -- any banned value
BEGIN
  WHILE seq_val IN (11, 20, 2056, 6547) LOOP
    seq_val := my_seq.nextval;
  END LOOP;
  RETURN seq_val;
END;
/

然后get_seq代替my_seq.nextval.

db<>fiddle demp范围较小,显示它跳过值。

当然也有缺点;您可能会看到上下文切换对性能的显着影响,尽管范围如此之小,您可能不会非常强烈地调用它。如果您的禁用号码发生变化,您必须更改函数,或者让函数从其他地方查找它们 - 例如,如果您要避免现有的 PK 值,您可能需要或想要这样做。必须引用不同的东西来检索nextval(间接通过函数)和currval(直接从序列中)可能会令人困惑。等等,但这是一个选择......

如果您要避免现有的 PK 值,那么另一种选择是坚持一个简单的序列并插入一个循环,当您没有遇到约束错误时退出 - 即通常在一次迭代之后。但目前尚不清楚您真正想要达到的目标。


推荐阅读