我们正在将我们的系统从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;
答案 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;
/
但是,如果您没有可用的命名约定,则可以执行以下操作:
最终结果应为:
BEGIN
reset_seq_val ( 'seq1', 'table1', 'col1');
reset_seq_val ( 'seq2', 'table2', 'col2');
...
END;
这里的努力工作将编制此列表,但一旦完成,您应该能够按需重复使用。
答案 1 :(得分:0)
如果在应用程序停顿时导出数据,则将数据导入12c,您不应该遇到关键问题。
如果升级12c,您也不应该遇到关键问题。
我参与了数十次12c迁移,从未听说过这个问题。