복붙노트

[SPRING] 오라클에서 시퀀스의 값을 재설정해야합니다.

SPRING

오라클에서 시퀀스의 값을 재설정해야합니다.

Java에서 웹 애플리케이션을 개발하기 위해 Spring과 Hibernate와 함께 일하고 있습니다. 내가 테이블을 가지고 있다고 가정합시다. 이 테이블에서 일부 레코드를 삭제할 때 가끔 기본 키 필드의 값을 다시 설정해야합니다.

테이블에 10 개의 레코드가 있고 마지막 5 개의 레코드를 삭제한다고 가정 해 봅시다. 이제 새 레코드를 삽입하면 기본 키 필드의 값은 6에서 시작해야하지만 11에서 시작됩니다.

MySql에서 기본 키 값을 6 (최대 +1)으로 시작해야하는 경우 다음 SQL 문을 실행하면됩니다.

alter table table_name auto_increment=1;

자동으로 auto_increment의 값을 해당 필드의 최대 + 1 값으로 재설정합니다 (개념적으로는 5 월이 맞지만 작동 할 수 있음).

Oracle (10g)에서 기본 키와 함께 시퀀스를 사용하고 있습니다. Oracle에서 일부 레코드가 데이터베이스에서 삭제 될 때 시퀀스 값을 최대 +1 값으로 재설정하는 방법이 있습니까?

해결법

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

    1.20 개의 레코드가 있고 레코드 5-10을 삭제하면 어떻게됩니까? 가운데에 간격이있어 시퀀스를 다시 설정하면 해결되지 않습니다. 시퀀스는 틈이없는 일련의 수를 생성하지 않으며 완벽한 1, 2 .. n입니다.

    20 개의 레코드가 있고 레코드 5-10을 삭제하면 어떻게됩니까? 가운데에 간격이있어 시퀀스를 다시 설정하면 해결되지 않습니다. 시퀀스는 틈이없는 일련의 수를 생성하지 않으며 완벽한 1, 2 .. n입니다.

    .nextval을 호출하고 사라진 값을 사용하지 않으면. 시퀀스를 삭제하고 다시 만드시겠습니까? 삽입을 시작하고 취소하면 Oracle은 사용자가 수행 한 작업을 롤백합니다. nocache를 설정하면 간격이 줄어들지 만 성능에 영향을줍니다. 그만한 가치가 있니?

    성능 문제를 피하려면 캐시가 모든 세션에서 한 번에 수행 할 것으로 예상되는 삽입 횟수로 설정되어야합니다. 시퀀스는 자물쇠없이 대리 키를 생성하는 매우 빠르고 확장 가능한 방법을 제공하여 양의 정수 집합을 다시 생성하지 않도록 설계되었습니다.

    하루가 끝나면 조금이라도 문제가되지 않습니다. 깨지지 않은 시퀀스를 테이블의 키로 사용한다면 시퀀스가 ​​아닌 데이터에 문제가있는 것입니다.

    실제로 질문에 대답하려면 다음과 같이해야합니다.

    최대 값을 찾는 것은 성능에 대한 다른 히트를 희생시키면서 시퀀스를 동적으로 재생성해야한다는 것을 의미합니다.

    이런 일이 발생하는 동안 당신의 테이블에 무언가를 삽입하려고하면 그것은 실패 할 것이고, 시퀀스를 사용하는 트리거 나 다른 객체를 무효화 할 수 있습니다 :

    declare
    
       l_max_value number;
    
    begin
    
       select max(id)
         into l_max_value
         from my_table;
    
       execute immediate 'drop sequence my_sequence_name';
    
       -- nocache is not recommended if you are inserting more than
       -- one row at a time, or inserting with any speed at all.
       execute immediate 'create sequence my_sequence_name
                               start with ' || l_max_value
                          || ' increment by 1
                               nomaxvalue
                               nocycle
                               nocache';
    
    end;
    /
    

    내가 말했듯이 이것은 권장되지 않으며 당신은 단지 틈을 무시해야합니다.

    설명서의 제안과는 달리, Jeffrey Kemp가 주석에서 제안한 것처럼 시퀀스를 삭제하고 다시 작성하지 않고이 작업을 수행 할 수있는 방법이 있습니다.

    즉,

    이것의 장점은 객체가 여전히 존재하고 트리거, 보조금 등이 여전히 유지된다는 것입니다. 단점은, 내가 보는 바와 같이, 다른 세션이 너의 것과 동시에이 음수만큼 증가하면 너는 너무 멀리 되돌아 갈 수 있다는 것이다.

    데모가 있습니다.

    SQL> create sequence test_seq
      2   start with 1
      3   increment by 1
      4   nomaxvalue
      5   nocycle
      6   nocache;
    
    Sequence created.
    
    SQL>
    SQL> create table tmp_test ( id number(16) );
    
    Table created.
    
    SQL>
    SQL> declare
      2     l_nextval number;
      3  begin
      4
      5    for i in 1 .. 20 loop
      6       insert into tmp_test values ( test_seq.nextval );
      7    end loop;
      8
      9  end;
     10  /
    
    PL/SQL procedure successfully completed.
    
    SQL>
    SQL> select test_seq.currval from dual;
    
       CURRVAL
    ----------
            20
    
    SQL>
    SQL> delete from tmp_test where id > 15;
    
    5 rows deleted.
    
    SQL> commit;
    
    Commit complete.
    
    SQL>
    SQL> declare
      2
      3     l_max_id number;
      4     l_max_seq number;
      5
      6  begin
      7
      8     -- Get the maximum ID
      9     select max(id) into l_max_id
     10       from tmp_test;
     11
     12     -- Get the current sequence value;
     13     select test_seq.currval into l_max_seq
     14       from dual;
     15
     16     -- Alter the sequence to increment by the difference ( -5 in this case )
    .
     17     execute immediate 'alter sequence test_seq
     18                          increment by ' || ( l_max_id - l_max_seq );
     19
     20     -- 'increment' by -5
     21     select test_seq.nextval into l_max_seq
     22       from dual;
     23
     24     -- Change the sequence back to normal
     25     execute immediate 'alter sequence test_seq
     26                          increment by 1';
     27
     28  end;
     29  /
    
    PL/SQL procedure successfully completed.
    
    SQL>
    SQL> select test_seq.currval from dual;
    
       CURRVAL
    ----------
            15
    
    SQL>
    
  2. ==============================

    2.다음은 또한 작동합니다 (순차 값을 100 씩 증가시킵니다).

    다음은 또한 작동합니다 (순차 값을 100 씩 증가시킵니다).

    select my_sequence.nextval from dual connect by level <= 100;
    
  3. ==============================

    3.오라클의 ALTER SEQUENCE 문서를 참조하면,

    오라클의 ALTER SEQUENCE 문서를 참조하면,

    다음 순번을 생성하려면 기본 키 열의 현재 최대 값을 전달해야합니다. 최신 레코드를 계속 h 제하고이 L 생성 된 순차 값을 재사용하려면이 순서를 다시 시작해야합니다. 시퀀스가 삭제되기 전에 서버가 다음 값에 대한 요청을 받으면 시퀀스를 삭제하면 SQLException이 발생할 수 있습니다.

    여기 Oracle Sequence에 대한 유용한 정보도 있습니다.

  4. ==============================

    4.이 트릭은 나를 위해 작동합니다. 내 순서 (USERSUTPL_USERUTPL_SQ)에서 마지막 숫자는 53이었다. 내 테이블의 마지막 이드는 83 세야.

    이 트릭은 나를 위해 작동합니다. 내 순서 (USERSUTPL_USERUTPL_SQ)에서 마지막 숫자는 53이었다. 내 테이블의 마지막 이드는 83 세야.

    SELECT MAX(ID) FROM USERSUTPL_USERUTPL
    

    그렇다면 83 - 53 = 31입니다. 그래서 :

    ALTER SEQUENCE USERSUTPL_USERUTPL_SQ INCREMENT BY +31;
    SELECT USERSUTPL_USERUTPL_SQ.NEXTVAL FROM dual;
    ALTER SEQUENCE USERSUTPL_USERUTPL_SQ INCREMENT BY 1;
    

    그리고 마지막 숫자가 바뀝니다. :디

  5. from https://stackoverflow.com/questions/10159840/need-to-reset-the-value-of-sequence-in-oracle by cc-by-sa and MIT license