【问题标题】:Reserve Number in Oracle Sequence GeneratorOracle 序列生成器中的保留编号
【发布时间】:2021-04-29 21:22:30
【问题描述】:

我们需要在使用 Oracle 序列生成器生成新号码时跳过几个已定义的号码。

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

可以吗?

【问题讨论】:

  • 序列定义中没有任何内在的东西可以做到这一点。为什么你需要跳过这些?为什么不从你想跳过的最高数字多 1 开始你的序列呢?将序列限制在仅 9999 的范围内有缺陷的设计或对如何最好地使用序列的理解有缺陷。当你的 seq.达到9999?您如何使用这些数字?
  • 我可以理解为什么有人想要保留一些数字,例如,为了测试的目的。我会通过从 10000 开始我的序列来简化它,而不用担心只有 4 个特殊数字。

标签: oracle oracle11g sequence


【解决方案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 值,那么另一种选择是坚持一个简单的序列并插入一个循环,当您没有遇到约束错误时退出 - 即通常在一次迭代之后。但目前尚不清楚您真正想要实现的目标。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多