sql >> データベース >  >> RDS >> Oracle

Oracle 10gでシーケンスの値を毎年自動的に0にリセットするにはどうすればよいですか?

    シーケンスは実際にはリセットされるようには設計されていません。ただし、テストデータを設定したり、本番データをテスト環境にマージしたりする場合など、シーケンスをリセットすることが望ましい場合があります。このタイプのアクティビティはではありません 通常は本番環境で行われます。

    このタイプの操作を本番環境に移行する場合は、徹底的にテストする必要があります。 (最も懸念されるのは、年の半ばなど、誤った時間にリセット手順が誤って実行される可能性があることです。

    シーケンスを削除して再作成することは、1つのアプローチです。操作としては、SEQUENCEに関する限り、かなり簡単です。

        DROP SEQUENCE MY_SEQ;
        CREATE SEQUENCE MY_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 0;
    

    [編集]MatthewWatsonが正しく指摘しているように、すべてのDDLステートメント(DROP、CREATE、ALTERなど)は暗黙のコミットを引き起こします。 [/編集]

    ただし、SEQUENCEで付与された特権はすべて削除されるため、それらを再付与する必要があります。シーケンスを参照するオブジェクトはすべて無効になります。これをより一般化するには、(シーケンスを削除する前に)特権を保存してから、それらを再付与する必要があります。

    2番目のアプローチは、既存のSEQUENCEを削除して再作成せずに、ALTERすることです。シーケンスのリセットは、INCREMENT値を負の値(現在の値と0の差)に変更し、.NEXTVALを1回だけ実行して現在の値を0に設定してから、INCREMENTを1に戻すことで実行できます。以前(手動で、テスト環境で)これと同じアプローチを使用して、シーケンスもより大きな値に設定しました。

    もちろん、これが正しく機能するためには、保険をかける必要があります。 この操作が実行されている間、他のセッションはシーケンスを参照しません。間違った瞬間に余分な.NEXTVALを実行すると、リセットが台無しになります。 (注:アプリケーションが個別のユーザーとしてではなく、シーケンスの所有者として接続している場合、データベース側でこれを実現することは困難になります。)

    毎年それを実現するには、仕事をスケジュールする必要があります。シーケンスのリセットは、識別子のYYYY部分のリセットと調整する必要があります。

    次に例を示します。

    http://www.jaredstill.com/content/reset-sequence.html

    [編集]

    未テスト シーケンスをリセットするためのPL/SQLブロックの1つの可能な設計のプレースホルダー

        declare
          pragma autonomous_transaction;
          ln_increment       number;
          ln_curr_val        number;
          ln_reset_increment number;
          ln_reset_val       number;
        begin
    
          -- save the current INCREMENT value for the sequence
          select increment_by
            into ln_increment
            from user_sequences
           where sequence_name = 'MY_SEQ';
    
          -- determine the increment value required to reset the sequence
          -- from the next fetched value to 0
          select -1 - MY_SEQ.nextval into ln_reset_increment from dual;
    
          -- fetch the next value (to make it the current value)
          select MY_SEQ.nextval into ln_curr from dual;
    
          -- change the increment value of the sequence to 
          EXECUTE IMMEDIATE 'alter sequence MY_SEQ increment by '
            || ln_reset_increment ||' minvalue 0';
    
          -- advance the sequence to set it to 0
          select MY_SEQ.nextval into ln_reset_val from dual;
    
          -- set increment back to the previous(ly saved) value
          EXECUTE IMMEDIATE 'alter sequence MY_SEQ increment by '
            || ln_increment ;
        end;
        /
    

    注:

    • シーケンスがリセットされている間、シーケンスをアクセスから保護するには、名前を変更しますか?
    • ここで機能するいくつかのテストケース。
    • 最初のパスで、正、昇順、増分1シーケンスの規範的なケースを確認します。
    • 新しいSEQUENCEを作成し、権限を追加し、既存のシーケンスと新しいシーケンスの名前を変更してから、依存関係を再コンパイルするのがより良いアプローチでしょうか?


    1. Postgresの制約

    2. Varcharを比較するOracleアップデート

    3. Postgresの2つの配列から値をテーブルに挿入するにはどうすればよいですか?

    4. PL/pgSQLで「$$」は何に使用されますか