sqloracle-databaseprimary-keyidentity-column

How do I correctly set the GENERATED BY DEFAULT AS IDENTITY sequence after inserting manual ids?


I have a table with a primary key sequence using the newer GENERATED BY DEFAULT AS IDENTITY feature:

CREATE TABLE test (
    id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    data VARCHAR
);

I then give the table a few values to begin with, overriding the sequence:

INSERT INTO test(id,data) VALUES (3,'something');
INSERT INTO test(id,data) VALUES (6,'something else');

Now if I add a few more values, letting the sequence do its thing:

INSERT INTO test(data) VALUES ('whatever');
INSERT INTO test(data) VALUES ('stuff');
INSERT INTO test(data) VALUES ('etc');

… I get an error:

ORA-00001: unique constraint (FIDDLE_CEYTNFUWNIDRFXSPTDWJ.SYS_C0054804) violated

OK, I understand the error: apparently the sequence starts at the beginning and begins to overlap with existing values.

How do I correctly set the sequence after the initial INSERT?

I have a fiddle at: https://dbfiddle.uk/MtPocwBq


Solution

  • Short answer is:

    ALTER TABLE test MODIFY ID GENERATED BY DEFAULT AS IDENTITY (START WITH LIMIT VALUE);
    

    Description in Oracle documentation:

    START WITH LIMIT VALUE, which is specific to identity_options, can only be used with ALTER TABLE MODIFY. If you specify START WITH LIMIT VALUE, then Oracle Database locks the table and finds the maximum identity column value in the table (for increasing sequences) or the minimum identity column value (for decreasing sequences) and assigns the value as the sequence generator's high water mark. The next value returned by the sequence generator will be the high water mark + INCREMENT BY integer for increasing sequences, or the high water mark - INCREMENT BY integer for decreasing sequences.

    And your modified dbfiddle.