2017-05-10 17 views
0

システムをOracle 11gから12Cに移行しています。私のシナリオはテストにのみ関係しています。ライブに行くとアプリケーションが中止され、シーケンスは生成されません。私はOracleにも新しくなっています。12Cでシーケンスを再作成

私たちのテスト環境では、シーケンス番号が原因でキー違反が発生しています。

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; 
+1

[既存の列の次の値にOracleシーケンスをリセットする最も良い方法は?](http://stackoverflow.com/questions/6099108/best-way-to-reset-an-oracle-sequence)既存の列の次の値) – OldProgrammer

+0

質問を再入力するには、テスト環境に入っていて、プロダクションから新しいデータをロードしたばかりで、テスト環境のシーケンスは今すぐになりますデータのキー値の後ろにあるため、テスト環境のシーケンスをバンプして、読み込んだデータの上に値を生成する必要があります。(うわ)。 @OldProgrammerが提供するリンクに従ってください。方法が示されているので、すべてのシーケンスをプログラムで実行できるはずです。 – unleashed

答えて

0

アプリケーションが休止しているときにデータをエクスポートし、データを12cにインポートすると、重要な問題は発生しません。

12cをアップグレードしても、重要な問題はありません。

私は数十の12c移行に関わってきましたが、この問題については聞いたことがありません。

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つの値を渡しワーカープロシージャを呼び出すラッパーのストアドプロシージャを生成
  • 上で見調整の増分を尽くすMAX値
  • ための指定されたテーブル/列を照会します。

最終的な結果は次のようになります。ここでのハードワークは、このリストをコンパイルするが、一度あなたがオンデマンドでそれを再利用することができるはず行われます

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

関連する問題