2016-06-16 4 views
0

データベースに定義された約100個のシーケンスがあります。これは、テストが実行された後にいくつかの数に設定されています。シーケンスの最小値の取得

例: シーケンス:suppier_seqがあります。 これは1で始まり、そのcurrvalは101です。

最小値に基づいて存在するすべてのシーケンスをリセットする必要があります。

私は一連のDDLを抽出した場合、それはでスタートとして存在価値が付属しています:私は最小値でシーケンスを再起動する必要が

CREATE SEQUENCE "RMS14"."SUPPLIER_SEQUENCE" MINVALUE 0 MAXVALUE 99999999999 INCREMENT BY 1 START WITH 101 CACHE 100 NOORDER NOCYCLE ; 

SQLを使用してシーケンスの最小値を取得するにはどうすればよいですか?

+0

MINVALUEでは最初に作成されたか、またはSTART WITH? *オリジナル* START WITHはとにかく保存されていないので、MINVALUE + 1で始めるとしますか?あなたは制御されたDDLスクリプトからそれらを削除して再作成することはできません - あなたはそれらをソース管理に持っていますか? –

+0

[this](http://stackoverflow.com/questions/51470/how-do-i-reset-a-sequence-in-oracle)を読んでください。 – StevieG

答えて

4

シーケンスの元の文字であるSTART WITHの値を知ることはできません。 MINVALUEでそれをベースにすることができます(ゼロであってもそれを使用するか、それを1つ追加するか、ゼロ以外の場合にのみ行う)。

あなたはuser_sequencesビューから独自のシーケンスの現在の値を取得し、それをループにPL/SQLブロックを使用して、ドロップが発生し、途中でステートメントを作成することができます。

set serveroutput on 
begin 
    for r in (
    select 'DROP SEQUENCE "' || sequence_name || '"' as drop_stmt, 
     'CREATE SEQUENCE "' || sequence_name || '"' 
     || ' MINVALUE ' || min_value 
     || ' MAXVALUE ' || max_value 
     || ' INCREMENT BY ' || increment_by 
     || ' START WITH ' || min_value 
     || case when cache_size = 0 then ' NOCACHE' else ' CACHE ' || cache_size end 
     || case when order_flag = 'Y' then ' ORDER' else ' NOORDER' end 
     || case when cycle_flag = 'Y' then ' CYCLE' else ' NOCYCLE' end 
     as create_stmt 
    from user_sequences 
) 
    loop 
    dbms_output.put_line(r.drop_stmt); 
-- execute immediate r.drop_stmt; 
    dbms_output.put_line(r.create_stmt); 
-- execute immediate r.create_stmt; 
    end loop; 
end; 
/

私がしましたexecute immediateステートメントは、何も確認せずにこれをコピーして貼り付けた事故を避けるためにコメントアウトしました。最初に実行するコマンドが表示されます。あなたが別のスキーマで作業し、必要な権限を持っている場合は

PL/SQL procedure successfully completed. 

DROP SEQUENCE "SUPPLIER_SEQUENCE" 
CREATE SEQUENCE "SUPPLIER_SEQUENCE" MINVALUE 0 MAXVALUE 99999999999 INCREMENT BY 1 START WITH 0 CACHE 100 NOORDER NOCYCLE 
... 

は、あなたの代わりに all_sequencesまたはdba_sequencesを照会し、所有者を指定することができます。

select 'DROP SEQUENCE "' || sequence_owner || '"."' || sequence_name ||'"' as drop_stmt, 
     'CREATE SEQUENCE "' || sequence_owner || '"."' || sequence_name || '"' 
     || ' MINVALUE ' || min_value 
... 

別のアプローチは、設定するために配列を変化させることですINCREMENT BYマイナス現在の最高値(または最高値からMINVALUEを引いたもの)を呼び出してnextvalと呼び出し、増分をリセットします。それはあなたがそれは、このようなループで直接行うの現在のシーケンス値を取得するために動的ステートメントの2番目のレベルを必要とするので、動的に少なくとも少し厄介ではありませんが、基本的に同じ考え方:

declare 
    l_nextval number; 
begin 
    for r in (
    select 'BEGIN EXECUTE IMMEDIATE ''ALTER SEQUENCE "' || sequence_name || '"' 
     || ' INCREMENT BY -''|| ("' || sequence_name || '".nextval - ' || min_value ||'); END;' 
     as alter_stmt_1, 
     'SELECT "' || sequence_name || '".nextval from dual' as adjust_stmt, 
     'ALTER SEQUENCE "' || sequence_name || '"' 
     || ' INCREMENT BY ' || increment_by 
     as alter_stmt_2 
    from user_sequences 
) 
    loop 
    dbms_output.put_line(r.alter_stmt_1); 
-- execute immediate r.alter_stmt_1; 
    dbms_output.put_line(r.adjust_stmt); 
-- execute immediate r.adjust_stmt into l_nextval; 
    dbms_output.put_line(r.alter_stmt_2); 
-- execute immediate r.alter_stmt_2; 
    end loop; 
end; 
/

PL/SQL procedure successfully completed. 

BEGIN EXECUTE IMMEDIATE 'ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY -'|| ("SUPPLIER_SEQUENCE".nextval - 0); END; 
SELECT "SUPPLIER_SEQUENCE".nextval from dual 
ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY 1 

また、生成することができますこのアプローチのためにビットすっきりおそらくあるループ、内部動的文:

declare 
    l_alter_stmt_1 varchar2(4000); 
    l_alter_stmt_2 varchar2(4000); 
    l_adjust_stmt varchar2(4000); 
    l_nextval number; 
begin 
    for r in (select * from user_sequences) loop 
    l_adjust_stmt := 'select "' || r.sequence_name || '".nextval from dual'; 
    execute immediate l_adjust_stmt into l_nextval; 
    l_alter_stmt_1 := 'ALTER SEQUENCE "' || r.sequence_name || '"' 
     || ' INCREMENT BY '|| (r.min_value - l_nextval); 
    l_alter_stmt_2 := 'ALTER SEQUENCE "' || r.sequence_name || '"' 
     || ' INCREMENT BY ' || r.increment_by; 
    dbms_output.put_line(l_alter_stmt_1); 
-- execute immediate r.alter_stmt_1; 
    dbms_output.put_line(l_adjust_stmt); 
-- execute immediate l_adjust_stmt into l_nextval; 
    dbms_output.put_line(l_alter_stmt_2); 
-- execute immediate l_alter_stmt_2; 
    end loop; 
end; 
/

PL/SQL procedure successfully completed. 

ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY -101 
select "SUPPLIER_SEQUENCE".nextval from dual 
ALTER SEQUENCE "SUPPLIER_SEQUENCE" INCREMENT BY 1 

問題は、具体的には、約11グラムが、this is even simpler in 12cあります。

関連する問題