복붙노트

[SQL] 어떻게 오라클에서 시퀀스를 재설정합니까?

SQL

어떻게 오라클에서 시퀀스를 재설정합니까?

PostgreSQL을, 나는 같은 것을 할 수 있습니다 :

ALTER SEQUENCE serial RESTART WITH 0;

오라클 상당이 있습니까?

해결법

  1. ==============================

    1.여기에 오라클 전문가 톰 카이트에서 0으로 모든 순서를 재설정을위한 좋은 과정이다. 너무 아래 링크의 장점과 단점에 대한 다양한 논의.

    여기에 오라클 전문가 톰 카이트에서 0으로 모든 순서를 재설정을위한 좋은 과정이다. 너무 아래 링크의 장점과 단점에 대한 다양한 논의.

    tkyte@TKYTE901.US.ORACLE.COM> 
    create or replace
    procedure reset_seq( p_seq_name in varchar2 )
    is
        l_val number;
    begin
        execute immediate
        'select ' || p_seq_name || '.nextval from dual' INTO l_val;
    
        execute immediate
        'alter sequence ' || p_seq_name || ' increment by -' || l_val || 
                                                              ' minvalue 0';
    
        execute immediate
        'select ' || p_seq_name || '.nextval from dual' INTO l_val;
    
        execute immediate
        'alter sequence ' || p_seq_name || ' increment by 1 minvalue 0';
    end;
    /
    

    이 페이지에서 : 동적 SQL 리셋 시퀀스 값 또 다른 좋은 토론은 여기에 있습니다 : 어떻게 순서를 재설정?

  2. ==============================

    2.진정한 다시 시작 AFAIK 수 없습니다. (내가 틀렸다면 수정하십시오!).

    진정한 다시 시작 AFAIK 수 없습니다. (내가 틀렸다면 수정하십시오!).

    당신이 0으로 설정하려는 경우에는, 당신은 단지 삭제하고 다시 만들 수 있습니다.

    특정 값으로 설정하려는 경우, 당신은 음의 값으로 INCREMENT을 설정하고 다음 값을 얻을 수 있습니다.

    당신의 순서가 500 인 경우 즉, 당신은을 통해 100으로 설정할 수 있습니다

    ALTER SEQUENCE serial INCREMENT BY -400;
    SELECT serial.NEXTVAL FROM dual;
    ALTER SEQUENCE serial INCREMENT BY 1;
    
  3. ==============================

    3.이것은 나의 접근 방식입니다 :

    이것은 나의 접근 방식입니다 :

    예:

    --Drop sequence
    
    DROP SEQUENCE MY_SEQ;
    
    -- Create sequence 
    
    create sequence MY_SEQ
    minvalue 1
    maxvalue 999999999999999999999
    start with 1
    increment by 1
    cache 20;
    
  4. ==============================

    4.나의 접근 방식은 Dougman의 예에 훑어 확장이다.

    나의 접근 방식은 Dougman의 예에 훑어 확장이다.

    확장은 ...

    매개 변수로 시드 값에 전달합니다. 왜? 나는 약간의 표에 사용 된 최대 ID에 시퀀스 다시 재설정 것은 전화를 좋아한다. 나는 기본 키 위반 원인 I는 고유 식별자에 대한 일련의 값을 사용하고 있지 어디에 충분히 높은를 일부 수준까지 NEXTVAL 다시 재설정 시퀀스의 모두에 대해 여러 호출을 실행하는 다른 스크립트에서이 시저를 호출 결국.

    또한 이전 MINVALUE 수여됩니다. 그것은 사실 지금보다 다음 값을 밀어 수 있습니다 경우 p_val 원하는 또는 MINVALUE가 현재 또는 계산 된 다음 값보다 높은 존재.

    무엇보다도, 지정된 값으로 재설정하기 위해 호출, 당신은 래퍼가 마지막 절차 "내 모든 순서를 수정"을 참조하십시오 때까지 그냥 기다려 될 수있다.

    create or replace
    procedure Reset_Sequence( p_seq_name in varchar2, p_val in number default 0)
    is
      l_current number := 0;
      l_difference number := 0;
      l_minvalue user_sequences.min_value%type := 0;
    
    begin
    
      select min_value
      into l_minvalue
      from user_sequences
      where sequence_name = p_seq_name;
    
      execute immediate
      'select ' || p_seq_name || '.nextval from dual' INTO l_current;
    
      if p_Val < l_minvalue then
        l_difference := l_minvalue - l_current;
      else
        l_difference := p_Val - l_current;
      end if;
    
      if l_difference = 0 then
        return;
      end if;
    
      execute immediate
        'alter sequence ' || p_seq_name || ' increment by ' || l_difference || 
           ' minvalue ' || l_minvalue;
    
      execute immediate
        'select ' || p_seq_name || '.nextval from dual' INTO l_difference;
    
      execute immediate
        'alter sequence ' || p_seq_name || ' increment by 1 minvalue ' || l_minvalue;
    end Reset_Sequence;
    

    그 과정은 그 자체로 유용한 모든하지만 지금은하자가 일련의 명명 규칙 및 기존 테이블 / 필드에 사용되는 최대 값을 찾고 프로그래밍 방식 및 지정은 모든 호출하는 다른 하나를 추가 ...

    create or replace
    procedure Reset_Sequence_to_Data(
      p_TableName varchar2,
      p_FieldName varchar2
    )
    is
      l_MaxUsed NUMBER;
    BEGIN
    
      execute immediate
        'select coalesce(max(' || p_FieldName || '),0) from '|| p_TableName into l_MaxUsed;
    
      Reset_Sequence( p_TableName || '_' || p_Fieldname || '_SEQ', l_MaxUsed );
    
    END Reset_Sequence_to_Data;
    

    이제 우리는 가스로 요리있어!

    테이블에있는 필드의 최대 값을 확인합니다 위의 절차는, 그 감지 된 최대 값으로 테이블 / 필드 쌍 원용하는 "Reset_Sequence"에서 시퀀스 이름을 작성합니다.

    이 퍼즐과 케이크 장식의 마지막 조각은 다음 온다 ...

    create or replace
    procedure Reset_All_Sequences
    is
    BEGIN
    
      Reset_Sequence_to_Data( 'ACTIVITYLOG', 'LOGID' );
      Reset_Sequence_to_Data( 'JOBSTATE', 'JOBID' );
      Reset_Sequence_to_Data( 'BATCH', 'BATCHID' );
    
    END Reset_All_Sequences;
    

    내 실제 데이터베이스에서이 메커니즘을 통해 리셋되는 약 백 다른 시퀀스가있다, 그래서 위의 해당 절차에 Reset_Sequence_to_Data 97 개 더 많은 통화가있다.

    그것은 사랑? 싫다? 무관심한?

  5. ==============================

    5.

    alter sequence serial restart start with 1;
    

    이 기능은 공식적으로 18C에 추가했지만 12.1 비공식적으로 볼 수 있었다.

    12.1이 문서화되지 않은 기능을 사용할 틀림없이 안전합니다. 구문은 공식 문서에 포함되지 않는다하더라도, 그것은 오라클 패키지 DBMS_METADATA_DIFF에 의해 생성됩니다. 내가 생산 시스템에 여러 번 사용했습니다. 그러나, 나는 오라클 서비스 요청을 생성하고 그것을하는 문서 버그가 아니라 기능이 진정되지 않는 것을 확인했습니다.

    18C에서,이 기능은 SQL 언어 구문에 표시되지 않지만, 데이터베이스 관리자 안내서에 포함되어 있습니다.

  6. ==============================

    6.다음 스크립트는 원하는 값으로 순서를 설정합니다

    다음 스크립트는 원하는 값으로 순서를 설정합니다

    갓 만든 순서라는 이름의 PCS_PROJ_KEY_SEQ 및 테이블 PCS_PROJ을 감안할 때 :

    BEGIN
       DECLARE
          PROJ_KEY_MAX       NUMBER := 0;
          PROJ_KEY_CURRVAL   NUMBER := 0;
       BEGIN
    
        SELECT MAX (PROJ_KEY) INTO PROJ_KEY_MAX FROM PCS_PROJ;
        EXECUTE IMMEDIATE 'ALTER SEQUENCE PCS_PROJ_KEY_SEQ INCREMENT BY ' || PROJ_KEY_MAX;
        SELECT PCS_PROJ_KEY_SEQ.NEXTVAL INTO PROJ_KEY_CURRVAL FROM DUAL;
        EXECUTE IMMEDIATE 'ALTER SEQUENCE PCS_PROJ_KEY_SEQ INCREMENT BY 1';
    
    END;
    END;
    /
    
  7. ==============================

    7.이 저장 프로 시저 내 순서를 다시 시작합니다 :

    이 저장 프로 시저 내 순서를 다시 시작합니다 :

    Create or Replace Procedure Reset_Sequence  
      is
      SeqNbr Number;
    begin
       /*  Reset Sequence 'seqXRef_RowID' to 0    */
       Execute Immediate 'Select seqXRef.nextval from dual ' Into SeqNbr;
       Execute Immediate 'Alter sequence  seqXRef increment by - ' || TO_CHAR(SeqNbr) ;
       Execute Immediate 'Select seqXRef.nextval from dual ' Into SeqNbr;
       Execute Immediate 'Alter sequence  seqXRef increment by 1';
    END;
    

    /

  8. ==============================

    8.이 오라클에서 시퀀스를 재설정하는 또 다른 방법은 다음과 같습니다 MAXVALUE 사이클 속성을 설정합니다. 시퀀스의 NEXTVAL가 MAXVALUE 안타 때 사이클 특성가 설정되어있는 경우,이 시퀀스의 MINVALUE에서 다시 시작합니다.

    이 오라클에서 시퀀스를 재설정하는 또 다른 방법은 다음과 같습니다 MAXVALUE 사이클 속성을 설정합니다. 시퀀스의 NEXTVAL가 MAXVALUE 안타 때 사이클 특성가 설정되어있는 경우,이 시퀀스의 MINVALUE에서 다시 시작합니다.

    에 의해 음의 증분을 설정에 비해이 방법의 장점은 기회를 감소 리셋 프로세스 실행, 당신은 리셋을 할 장애의 형태를 취할 필요가있는 동안 순서를 계속 사용할 수 있습니다.

    절차는 다음의 순서는 프로 시저에서 NEXTVAL를 선택하고, 사이클 특성을 설정 사이에 다시 액세스되는 경우에는 버퍼를 허용하는 임의의 파라미터를 포함하므로 MAXVALUE의 값은, 현재 NEXTVAL보다 커야한다.

    create sequence s start with 1 increment by 1;
    
    select s.nextval from dual
    connect by level <= 20;
    
       NEXTVAL
    ----------
             1 
    ...
            20
    
    create or replace procedure reset_sequence ( i_buffer in pls_integer default 0)
    as
      maxval pls_integer;
    begin
    
      maxval := s.nextval + greatest(i_buffer, 0); --ensure we don't go backwards!
      execute immediate 'alter sequence s cycle minvalue 0 maxvalue ' || maxval;
      maxval := s.nextval;
      execute immediate 'alter sequence s nocycle maxvalue 99999999999999';
    
    end;
    /
    show errors
    
    exec reset_sequence;
    
    select s.nextval from dual;
    
       NEXTVAL
    ----------
             1 
    

    스탠드와 같은 절차는 또 다른 세션이 또는 당신을 위해 문제가되지 않을 수도 있습니다 0 값을 가져옵니다 가능성이 있습니다. 이 경우, 당신은 항상 수 :

  9. ==============================

    9.Jezus, 단지 인덱스 다시 시작을위한 모든 프로그래밍 ... 아마도 내가 바보지만, 전 오라클 (12) (다시 시작 기능이있는)를 들어, simpel 잘못된 것입니다 :

    Jezus, 단지 인덱스 다시 시작을위한 모든 프로그래밍 ... 아마도 내가 바보지만, 전 오라클 (12) (다시 시작 기능이있는)를 들어, simpel 잘못된 것입니다 :

    drop sequence blah;
    create sequence blah 
    

    ?

  10. ==============================

    10.아래 그림과 같이 1) 시퀀스를 만드는 경우를 가정 해 :

    아래 그림과 같이 1) 시퀀스를 만드는 경우를 가정 해 :

    CREATE SEQUENCE TESTSEQ
    INCREMENT BY 1
    MINVALUE 1
    MAXVALUE 500
    NOCACHE
    NOCYCLE
    NOORDER
    

    2) 이제 시퀀스에서 값을 가져옵니다. 아래 그림과 같이 내가 가져온 네 번이 있다고 할 수 있습니다.

    SELECT TESTSEQ.NEXTVAL FROM dual
    SELECT TESTSEQ.NEXTVAL FROM dual
    SELECT TESTSEQ.NEXTVAL FROM dual
    SELECT TESTSEQ.NEXTVAL FROM dual
    

    3) 위의 네 개의 명령을 실행 한 후, 시퀀스의 값은 이제 다시 1 시퀀스의 값을 다시 4 있다고 가정 할 것이다. 다음 단계를 따릅니다. 아래 그림과 같이 같은 순서로 모든 단계를 따르십시오 :

  11. ==============================

    11.다시 변경 후 시퀀스의 증가 값을 변경하여 증가하고, 꽤 고통이다, 플러스 당신은 당신이 떨어졌다하는 것처럼 보조금을 모두 다시 설정 / 다시 순서에 가지고 있지의 추가 혜택이있다.

    다시 변경 후 시퀀스의 증가 값을 변경하여 증가하고, 꽤 고통이다, 플러스 당신은 당신이 떨어졌다하는 것처럼 보조금을 모두 다시 설정 / 다시 순서에 가지고 있지의 추가 혜택이있다.

  12. ==============================

    12.내 모든 순서를 재설정 할 수있는 블록을 만들 :

    내 모든 순서를 재설정 할 수있는 블록을 만들 :

    DECLARE
        I_val number;
    BEGIN
        FOR US IN
            (SELECT US.SEQUENCE_NAME FROM USER_SEQUENCES US)
        LOOP
            execute immediate 'select ' || US.SEQUENCE_NAME || '.nextval from dual' INTO l_val;
            execute immediate 'alter sequence ' || US.SEQUENCE_NAME || ' increment by -' || l_val || ' minvalue 0';
            execute immediate 'select ' || US.SEQUENCE_NAME || '.nextval from dual' INTO l_val;
            execute immediate 'alter sequence ' || US.SEQUENCE_NAME || ' increment by 1 minvalue 0';
        END LOOP;
    END;
    
  13. ==============================

    13.여기에 훨씬 더 시퀀스에 의해 반환 된 다음 값을 변경하기위한보다 강력한 방법입니다, 플러스.

    여기에 훨씬 더 시퀀스에 의해 반환 된 다음 값을 변경하기위한보다 강력한 방법입니다, 플러스.

    여기 코드는 :

    CREATE OR REPLACE PROCEDURE alter_sequence(
        seq_name      user_sequences.sequence_name%TYPE
      , next_value    user_sequences.last_number%TYPE := null
      , increment_by  user_sequences.increment_by%TYPE := null
      , min_value     user_sequences.min_value%TYPE := null
      , max_value     user_sequences.max_value%TYPE := null
      , cycle_flag    user_sequences.cycle_flag%TYPE := null
      , cache_size    user_sequences.cache_size%TYPE := null
      , order_flag    user_sequences.order_flag%TYPE := null)
      AUTHID CURRENT_USER
    AS
      l_seq user_sequences%rowtype;
      l_old_cache user_sequences.cache_size%TYPE;
      l_next user_sequences.min_value%TYPE;
    BEGIN
      -- Get current sequence settings as defaults
      SELECT * INTO l_seq FROM user_sequences WHERE sequence_name = seq_name;
    
      -- Update target settings
      l_old_cache := l_seq.cache_size;
      l_seq.increment_by := nvl(increment_by, l_seq.increment_by);
      l_seq.min_value    := nvl(min_value, l_seq.min_value);
      l_seq.max_value    := nvl(max_value, l_seq.max_value);
      l_seq.cycle_flag   := nvl(cycle_flag, l_seq.cycle_flag);
      l_seq.cache_size   := nvl(cache_size, l_seq.cache_size);
      l_seq.order_flag   := nvl(order_flag, l_seq.order_flag);
    
      IF next_value is NOT NULL THEN
        -- Determine next value without exceeding limits
        l_next := LEAST(GREATEST(next_value, l_seq.min_value+1),l_seq.max_value);
    
        -- Grab the actual latest seq number
        EXECUTE IMMEDIATE
            'ALTER SEQUENCE '||l_seq.sequence_name
                || ' INCREMENT BY 1'
                || ' MINVALUE '||least(l_seq.min_value,l_seq.last_number-l_old_cache)
                || ' MAXVALUE '||greatest(l_seq.max_value,l_seq.last_number)
                || ' NOCACHE'
                || ' ORDER';
        EXECUTE IMMEDIATE 
          'SELECT '||l_seq.sequence_name||'.NEXTVAL FROM DUAL'
        INTO l_seq.last_number;
    
        l_next := l_next-l_seq.last_number-1;
    
        -- Reset the sequence number
        IF l_next <> 0 THEN
          EXECUTE IMMEDIATE 
            'ALTER SEQUENCE '||l_seq.sequence_name
                || ' INCREMENT BY '||l_next
                || ' MINVALUE '||least(l_seq.min_value,l_seq.last_number)
                || ' MAXVALUE '||greatest(l_seq.max_value,l_seq.last_number)
                || ' NOCACHE'
                || ' ORDER';
          EXECUTE IMMEDIATE 
            'SELECT '||l_seq.sequence_name||'.NEXTVAL FROM DUAL'
          INTO l_next;
        END IF;
      END IF;
    
      -- Prepare Sequence for next use.
      IF COALESCE( cycle_flag
                 , next_value
                 , increment_by
                 , min_value
                 , max_value
                 , cache_size
                 , order_flag) IS NOT NULL
      THEN
        EXECUTE IMMEDIATE 
          'ALTER SEQUENCE '||l_seq.sequence_name
              || ' INCREMENT BY '||l_seq.increment_by
              || ' MINVALUE '||l_seq.min_value
              || ' MAXVALUE '||l_seq.max_value
              || CASE l_seq.cycle_flag
                 WHEN 'Y' THEN ' CYCLE' ELSE ' NOCYCLE' END
              || CASE l_seq.cache_size
                 WHEN 0 THEN ' NOCACHE'
                 ELSE ' CACHE '||l_seq.cache_size END
              || CASE l_seq.order_flag
                 WHEN 'Y' THEN ' ORDER' ELSE ' NOORDER' END;
      END IF;
    END;
    
  14. ==============================

    14.이 일이 한 번 내 프로젝트에서, 그 사람이 수동으로 순서를 사용하지 않고 레코드를 입력, 따라서 나는 SQL 코드 아래에 작성하는 수동 시퀀스 값을 다시 설정해야합니다 :

    이 일이 한 번 내 프로젝트에서, 그 사람이 수동으로 순서를 사용하지 않고 레코드를 입력, 따라서 나는 SQL 코드 아래에 작성하는 수동 시퀀스 값을 다시 설정해야합니다 :

    declare
    max_db_value number(10,0);
    cur_seq_value number(10,0);
    counter number(10,0);
    difference number(10,0);
    dummy_number number(10);
    
    begin
    
    -- enter table name here
    select max(id) into max_db_value from persons;
    -- enter sequence name here
    select last_number into cur_seq_value from user_sequences where  sequence_name = 'SEQ_PERSONS';
    
    difference  := max_db_value - cur_seq_value;
    
     for counter in 1..difference
     loop
        -- change sequence name here as well
        select SEQ_PERSONS.nextval into dummy_number from dual;
     end loop;
    end;
    

    순서가 지체되는 경우 참고, 위의 코드가 작동합니다 바랍니다.

  15. ==============================

    15.당신은 아래의 CYCLE 옵션을 사용할 수 있습니다 :

    당신은 아래의 CYCLE 옵션을 사용할 수 있습니다 :

    CREATE SEQUENCE test_seq
    MINVALUE 0
    MAXVALUE 100
    START WITH 0
    INCREMENT BY 1
    CYCLE;
    

    시퀀스 MAXVALUE (100)에 도달이 경우에있어서, 상기 MINVALUE (0)로 재순환된다.

    감소 시퀀스의 경우에, 시퀀스는 MAXVALUE 재순환 것이다.

  16. ==============================

    16.여기에 모든 자동 증가 시퀀스는 실제 데이터와 일치하는 방법은 다음과 같습니다

    여기에 모든 자동 증가 시퀀스는 실제 데이터와 일치하는 방법은 다음과 같습니다

    노트:

  17. ==============================

    17.나는 사용자가 업데이트하는 값, 시스템 GET 및 사용 변수를 알 필요하지 않는 대안을합니다.

    나는 사용자가 업데이트하는 값, 시스템 GET 및 사용 변수를 알 필요하지 않는 대안을합니다.

    --Atualizando sequence da tabela SIGA_TRANSACAO, pois está desatualizada
    DECLARE
     actual_sequence_number INTEGER;
     max_number_from_table INTEGER;
     difference INTEGER;
    BEGIN
     SELECT [nome_da_sequence].nextval INTO actual_sequence_number FROM DUAL;
     SELECT MAX([nome_da_coluna]) INTO max_number_from_table FROM [nome_da_tabela];
     SELECT (max_number_from_table-actual_sequence_number) INTO difference FROM DUAL;
    IF difference > 0 then
     EXECUTE IMMEDIATE CONCAT('alter sequence [nome_da_sequence] increment by ', difference);
     --aqui ele puxa o próximo valor usando o incremento necessário
     SELECT [nome_da_sequence].nextval INTO actual_sequence_number from dual;
    --aqui volta o incremento para 1, para que futuras inserções funcionem normalmente
     EXECUTE IMMEDIATE 'ALTER SEQUENCE [nome_da_sequence] INCREMENT by 1';
     DBMS_OUTPUT.put_line ('A sequence [nome_da_sequence] foi atualizada.');
    ELSE
     DBMS_OUTPUT.put_line ('A sequence [nome_da_sequence] NÃO foi atualizada, já estava OK!');
    END IF;
    END;
    
  18. ==============================

    18.나를 위해 일한 저장 프로 시저

    나를 위해 일한 저장 프로 시저

    create or replace
    procedure reset_sequence( p_seq_name in varchar2, tablename in varchar2 )
    is
        l_val number;
        maxvalueid number;
    begin
        execute immediate 'select ' || p_seq_name || '.nextval from dual' INTO l_val;
        execute immediate 'select max(id) from ' || tablename INTO maxvalueid;
        execute immediate 'alter sequence ' || p_seq_name || ' increment by -' || l_val || ' minvalue 0';
        execute immediate 'select ' || p_seq_name || '.nextval from dual' INTO l_val;
        execute immediate 'alter sequence ' || p_seq_name || ' increment by '|| maxvalueid ||' minvalue 0';  
        execute immediate 'select ' || p_seq_name || '.nextval from dual' INTO l_val;
        execute immediate 'alter sequence ' || p_seq_name || ' increment by 1 minvalue 0';
    end;
    

    저장 프로 시저를 사용하는 방법 :

    execute reset_sequence('company_sequence','company');
    
  19. from https://stackoverflow.com/questions/51470/how-do-i-reset-a-sequence-in-oracle by cc-by-sa and MIT license