Oracle 序列生成器中的保留编号
Posted
技术标签:
【中文标题】Oracle 序列生成器中的保留编号【英文标题】:Reserve Number in Oracle Sequence Generator 【发布时间】:2021-04-29 21:22:30 【问题描述】:我们需要在使用 Oracle 序列生成器生成新号码时跳过几个已定义的号码。
例如:- 我们定义的范围为 0001-9999,但在此范围内,Oracle 排序器永远不会生成数字 0011、0020、2056、6547。
可以吗?
【问题讨论】:
序列定义中没有任何内在的东西可以做到这一点。为什么你需要跳过这些?为什么不从你想跳过的最高数字多 1 开始你的序列呢?将序列限制在仅 9999 的范围内有缺陷的设计或对如何最好地使用序列的理解有缺陷。当你的 seq.达到9999?您如何使用这些数字? 我可以理解为什么有人想要保留一些数字,例如,为了测试的目的。我会通过从 10000 开始我的序列来简化它,而不用担心只有 4 个特殊数字。 【参考方案1】:可以吗?
有点……只要在 2057 开始序列并在 6546 停止它,那么您将永远不会生成任何这些值。
如果您想从 1 开始到 9999 跳过这些值,那么,不,Oracle 序列中没有任何内容允许您这样做。
【讨论】:
【参考方案2】:您不能仅在内置序列机制中做到这一点。作为一种解决方法,您可以有一个跳过禁止值的包装函数,例如:
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 值,那么另一种选择是坚持一个简单的序列并插入一个循环,当您没有遇到约束错误时退出 - 即通常在一次迭代之后。但目前尚不清楚您真正想要实现的目标。
【讨论】:
以上是关于Oracle 序列生成器中的保留编号的主要内容,如果未能解决你的问题,请参考以下文章
Oracle数据库导入Excel铺底数据 -含自动插入生成自定义序列号