How to create an Oracle sequence starting with max value from a table?

后端 未结 8 1168
[愿得一人]
[愿得一人] 2020-12-02 20:14

Trying to create a sequence in Oracle that starts with the max value from a specific table. Why does this not work?

CREATE SEQUENCE transaction_sequence
  MI         


        
相关标签:
8条回答
  • 2020-12-02 20:25

    you might want to start with max(trans_seq_no) + 1.

    watch:

    SQL> create table my_numbers(my_number number not null primary key);
    
    Table created.
    
    SQL> insert into my_numbers(select rownum from user_objects);
    
    260 rows created.
    
    SQL> select max(my_number) from my_numbers;
    
    MAX(MY_NUMBER)
    --------------
               260
    
    SQL> create sequence my_number_sn start with 260;
    
    Sequence created.
    
    SQL> insert into my_numbers(my_number) values (my_number_sn.NEXTVAL);
    insert into my_numbers(my_number) values (my_number_sn.NEXTVAL)
    *
    ERROR at line 1:
    ORA-00001: unique constraint (NEIL.SYS_C00102439) violated
    

    When you create a sequence with a number, you have to remember that the first time you select against the sequence, Oracle will return the initial value that you assigned it.

    SQL> drop sequence my_number_sn;
    
    Sequence dropped.
    
    SQL> create sequence my_number_sn start with 261;
    
    Sequence created.
    
    SQL>  insert into my_numbers(my_number) values (my_number_sn.NEXTVAL);
    
    1 row created.
    

    If you're trying to do the 'gapless' thing, I strongly advise you to

    1 not do it, and #2 not use a sequence for it.

    0 讨论(0)
  • 2020-12-02 20:25

    If you can use PL/SQL, try (EDIT: Incorporates Neil's xlnt suggestion to start at next higher value):

    SELECT 'CREATE SEQUENCE transaction_sequence MINVALUE 0 START WITH '||MAX(trans_seq_no)+1||' INCREMENT BY 1 CACHE 20'
      INTO v_sql
      FROM transaction_log;
    
    EXECUTE IMMEDIATE v_sql;
    

    Another point to consider: By setting the CACHE parameter to 20, you run the risk of losing up to 19 values in your sequence if the database goes down. CACHEd values are lost on database restarts. Unless you're hitting the sequence very often, or, you don't care that much about gaps, I'd set it to 1.

    One final nit: the values you specified for CACHE and INCREMENT BY are the defaults. You can leave them off and get the same result.

    0 讨论(0)
  • 2020-12-02 20:30

    Bear in mid, the MAX value will only be the maximum of committed values. It might return 1234, and you may need to consider that someone has already inserted 1235 but not committed.

    0 讨论(0)
  • 2020-12-02 20:35

    You can't use a subselect inside a CREATE SEQUENCE statement. You'll have to select the value beforehand.

    0 讨论(0)
  • 2020-12-02 20:35

    use dynamic sql

    BEGIN
                DECLARE
                maxId NUMBER;
                  BEGIN
                  SELECT MAX(id)+1
                  INTO maxId
                  FROM table_name;          
                  execute immediate('CREATE SEQUENCE sequane_name MINVALUE '||maxId||' START WITH '||maxId||' INCREMENT BY 1 NOCACHE NOCYCLE');
                  END;
    END;
    
    0 讨论(0)
  • 2020-12-02 20:37

    Based on Ivan Laharnar with less code and simplier:

    declare
        lastSeq number;
    begin
        SELECT MAX(ID) + 1 INTO lastSeq FROM <TABLE_NAME>;
        if lastSeq IS NULL then lastSeq := 1; end if;
        execute immediate 'CREATE SEQUENCE <SEQUENCE_NAME> INCREMENT BY 1 START WITH ' || lastSeq || ' MAXVALUE 999999999 MINVALUE 1 NOCACHE';
    end;
    
    0 讨论(0)
提交回复
热议问题