Последовательность Oracle начиная с 2 вместо 1

Неожиданное поведение:

Я встречаю странное поведение последовательностей Oracle с 11g (работает с 10g):

CREATE SEQUENCE test_sequence START WITH 1;
CREATE TABLE test_table ( val INT );

INSERT INTO test_table VALUES ( test_sequence.NEXTVAL );

Даже если последовательность начинается с 1, первое введенное значение 2:

SELECT * FROM test_table;

       VAL
----------
         2

Ожидаемое поведение:

Выбор NEXTVAL без вставки работает как ожидалось:

CREATE SEQUENCE test_sequence_2 START WITH 1;

SELECT test_sequence_2.NEXTVAL FROM dual

   NEXTVAL
----------
         1

Вопрос:

Может ли кто-нибудь воспроизвести это с помощью Oracle 11g? Это известная проблема?

Я использую Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production.

Ответ 1

Это задокументировано в 11.2 Справочнике по языку SQL, где говорится:

Если вы попытаетесь вставить значение последовательности в таблицу, которая использует создание отложенного сегмента, первое значение, которое возвращает последовательность, будет пропущено.

См. ссылку в ответе Джеффри Кемпа на заметку о поддержке Microsoft (Metalink) и обходной путь.

Ответ 2

Я бы сказал, что причиной является "недокументированная функция". См. Мой документ поддержки Oracle ID 1273858.1 (который, к сожалению, находится за платой и не может быть скопирован здесь).

Попробуйте это без создания отложенного сегмента и проверьте, не устранена ли проблема.

Ответ 3

Я не могу воспроизвести на 11G, т.е. таблица содержит 1 после выполнения ваших шагов.

Однако, это спорно, следует ли это рассматривать как "проблему", потому что последовательности никогда не гарантированы бесщелевыми. Какие гарантии START WITH гарантируют, что последовательность никогда не вернет значение ниже, чем указанное начальное значение - например. чтобы избежать конфликтов с существующими данными. Я согласен с тем, что то, что вы видите, удивительно, и мне было бы интересно узнать причину!

Ответ 4

Использование:

CREATE SEQUENCE SQ_SEQUENCE_NAME
    INCREMENT BY 1
    START WITH 1
    MINVALUE 0  -- This will ensure start at 1!
    MAXVALUE 99
    NOCYCLE
    NOCACHE
    ORDER;