每月重置 Oracle 序列的最佳策略

Best strategy to reset Oracle sequence monthly

我正在寻找重置用于生成唯一键的序列的最佳策略。这些键是使用前缀值构建的,也是由月份和年份值的组合生成的,如下例所示:

2020060100000001 - 年(4d)月(2d)序(8d)

序列值必须在每个新月的第一秒重新开始。

是否有任何 Oracle 事件允许调用基于这种情况的函数或过程来完成这项工作?

谁能帮我提点意见和经验?

非常感谢! 罗德里戈

每个月重置序列不是一个有效的方法。基本上你违反了顺序的使用。从你的问题我可以理解,你想将年份和月份附加到你的专栏。在这种情况下,您可以在插入时简单地连接,

year||month||sequence_name.nextval

Eg: 2020||02||sequence_name.nextval

如果你还想重置,你可以创建一个触发器来每月重置序列,

如果你真的想设置一个序列的值,你可以使用类似下面的东西:

PROCEDURE SET_SEQUENCE(pinSequence_owner IN VARCHAR2,
                       pinSequence_name  IN VARCHAR2,
                       pinNew_next_value IN NUMBER,
                       pinDebug          IN BOOLEAN := FALSE)
IS
  strSQL               VARCHAR2(4000);
  nNext_number         NUMBER;
  nOriginal_increment  NUMBER;
  nNew_nextval         NUMBER;
  nNew_last_number     NUMBER;
BEGIN
  strSQL := 'SELECT s.LAST_NUMBER, INCREMENT_BY ' ||
              'FROM DBA_SEQUENCES s ' ||
              'WHERE s.SEQUENCE_OWNER = ''' || pinSequence_owner || ''' AND ' ||
                    's.SEQUENCE_NAME = ''' || pinSequence_name || '''';
  EXECUTE IMMEDIATE strSQL INTO nNext_number, nOriginal_increment;

  -- Note that DBA_SEQUENCES.LAST_NUMBER represents the *next* number which will be
  -- returned by a call to NEXTVAL.

  IF pinNew_next_value NOT IN (nNext_number-1, nNext_number)
  THEN
    strSQL := 'ALTER SEQUENCE ' || pinSequence_owner || '.' || pinSequence_name ||
              ' INCREMENT BY ' || TO_CHAR(pinNew_next_value - nNext_number) || ' NOCACHE';
    EXECUTE IMMEDIATE strSQL;

    strSQL := 'SELECT ' || pinSequence_owner || '.' || pinSequence_name || '.NEXTVAL FROM DUAL';
    EXECUTE IMMEDIATE strSQL INTO nNew_nextval;

    strSQL := 'ALTER SEQUENCE ' || pinSequence_owner || '.' || pinSequence_name ||
              ' INCREMENT BY ' || nOriginal_increment || ' NOCACHE';
    EXECUTE IMMEDIATE strSQL;

    strSQL := 'SELECT s.LAST_NUMBER FROM DBA_SEQUENCES s WHERE s.SEQUENCE_OWNER = ''' || pinSequence_owner ||
                ''' AND s.SEQUENCE_NAME = ''' || pinSequence_name || '''';
    EXECUTE IMMEDIATE strSQL INTO nNew_last_number;
  END IF;
END SET_SEQUENCE;