Oracle 在12C中重新创建序列
我们正在将我们的系统从Oracle 11g迁移到12C,我的场景只涉及测试,当我们上线时,我们将暂停应用程序,这样就不会生成更多的序列。我对甲骨文也是新手 在我们的测试环境中,由于序列号落后,我们得到了密钥冲突 我需要循环浏览343个现有序列,获得最大数量的序列,并从每个表中当前最大数量+1开始重建/重新创建序列。下面来自另一个线程的代码可能可以工作,但我需要它在343个表之间循环。从11g中的用户_序列中获取最大序列号Oracle 在12C中重新创建序列,oracle,Oracle,我们正在将我们的系统从Oracle 11g迁移到12C,我的场景只涉及测试,当我们上线时,我们将暂停应用程序,这样就不会生成更多的序列。我对甲骨文也是新手 在我们的测试环境中,由于序列号落后,我们得到了密钥冲突 我需要循环浏览343个现有序列,获得最大数量的序列,并从每个表中当前最大数量+1开始重建/重新创建序列。下面来自另一个线程的代码可能可以工作,但我需要它在343个表之间循环。从11g中的用户_序列中获取最大序列号 declare ex number; be
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;
若您在应用程序停止运行时导出数据,然后将数据导入12c,那个么您就不会有关键问题 如果升级12c到位,您也不应该有关键问题
我参与过几十次12c迁移,从未听说过这个问题。这就是有一个合适的命名约定/标准的地方 在我设计的数据库中,每个表都有一个3或4个字符的别名,我们用这个别名命名索引、约束等 如果名为_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;
这里的艰苦工作将是编译此列表,但一旦完成,您应该能够按需重新使用它。可能的重复要重新回答您的问题,您在一个测试环境中,刚刚从生产中加载了新数据,并且您在测试环境中的序列现在“落后于”数据中的键值,因此,您需要增加测试环境序列,以便它们在刚刚加载的数据之上生成值。呼。按照提供的@OldProgrammer链接进行操作,因为它显示了方法,您应该能够以编程方式完成所有序列。