在12C中重新创建序列

时间:2017-05-10 13:30:46

标签: oracle

我们正在将我们的系统从Oracle 11g迁移到12C,我的方案仅涉及测试,当我们上线时,我们将暂停应用程序,以便不再生成序列。我也是Oracle的新手。

在我们的测试环境中,由于序列号落后,我们正在获得关键违规。

我需要遍历343个现有序列,获得最高数字并重建/重新创建序列,从每个表中当前最高数字+1开始。下面的代码(来自另一个线程)可能有效,但是我需要循环遍历343个表。从11g中的user_sequences获取最大序列号;

     declare
      ex number;
     begin
      select MAX(MAX_FK_ID)  + 1 into ex from TABLE;
       If ex > 0 then
        begin
                execute immediate 'DROP SEQUENCE SQ_NAME';
           exception when others then
             null;
        end;
        execute immediate 'CREATE SEQUENCE SQ_NAME INCREMENT BY 1 START 
        WITH ' || ex || ' NOCYCLE CACHE 20 NOORDER';
       end if;
    end;

2 个答案:

答案 0 :(得分:1)

这是一个体面的命名约定/标准有帮助的地方。

在我设计的数据库中,每个表都有一个3或4个字符的别名,我们用该别名命名索引,约束等内容。

如果名为the_table的表具有别名ttab,则主键列为ttab_id,主键约束为pk_ttab,而用于ttab_id的序列为seq_ttab_id。

考虑到这一点,你会写下面的人(没有经过测试,所以可能需要一点调整,但希望你能得到一般的想法):

DECLARE
   CURSOR cseq IS
      SELECT sequence_name seqname FROM user_sequences;
   tabname VARCHAR2(30);
   colname VARCHAR2(30);
   cmd     VARCHAR2(1000);
   maxval  NUMBER;
BEGIN
   FOR r IN cseq LOOP
      /*
      ** Now get corresponding table/column name matching the sequence name
      */
      SELECT table_name, column_name 
      INTO tabname, colname
      FROM user_cons_columns #
      WHERE column_name = REPLACE ( r.seqname, 'SEQ_', '' ) 
      AND constraint_name = REPLACE( REPLACE(r.seqname, '_ID', '' ), 'SEQ_', 'PK_' );
      /*
      ** Query the table to get the current maximum value - could use stats
      */
      cmd := 'SELECT MAX(' || colname || ') FROM ' || tabname;
      EXECUTE IMMEDIATE cmd INTO maxval;
      /*
      ** Set sequence to inc by that amount
      */
      cmd := 'alter sequence ' || r.seqname || ' INCREMENT BY ' || maxval;
      EXECUTE IMMEDIATE cmd;
      /*
      ** SELECT the sequence to bump its value up
      */
      cmd := 'SELECT ' || r.seqname || '.nextval FROM DUAL';
      EXECUTE IMMEDIATE cmd INTO maxval;
      /*
      ** Set sequence inc by back down
      */
      cmd := 'alter sequence ' || r.seqname || ' INCREMENT BY 1';
      EXECUTE IMMEDIATE cmd;
   END LOOP;
END;
/

但是,如果您没有可用的命名约定,则可以执行以下操作:

  • 创建一个接受序列名称,表名称的存储过程, 列名作为参数。
  • 该过程将查询给定的表/列以获取最大值
  • 然后程序将通过上面的调整进行增量
  • 现在生成一个包装器存储过程,该过程将调用传递3个值的工作程序。

最终结果应为:

BEGIN
  reset_seq_val ( 'seq1', 'table1', 'col1');
  reset_seq_val ( 'seq2', 'table2', 'col2');
...
END;

这里的努力工作将编制此列表,但一旦完成,您应该能够按需重复使用。

答案 1 :(得分:0)

如果在应用程序停顿时导出数据,则将数据导入12c,您不应该遇到关键问题。

如果升级12c,您也不应该遇到关键问题。

我参与了数十次12c迁移,从未听说过这个问题。