Столбец идентификатора Oracle и вставить в

В Oracle 12 появилась приятная функция (которая должна была быть там уже давно) - столбцы идентификации. Итак, здесь script:

CREATE TABLE test (
    a INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    b VARCHAR2(10)
);

-- Ok
INSERT INTO test (b) VALUES ('x');

-- Ok
INSERT INTO test (b)
SELECT 'y' FROM dual;

-- Fails
INSERT INTO test (b)
SELECT 'z' FROM dual UNION ALL SELECT 'zz' FROM DUAL;

Первые две вставки запускаются без проблем, предоставляя значения для 'a' из 1 и 2. Но третий не работает с ORA-01400: cannot insert NULL into ("DEV"."TEST"."A"). Почему это случилось? Жук? Ничего подобного не упоминается в части документации о ограничениях столбца идентификатора. Или я просто делаю что-то не так?

Ответ 1

Я полагаю, что ниже работает запрос, я не тестировал!

INSERT INTO Test (b)
SELECT * FROM
(
   SELECT 'z' FROM dual
   UNION ALL
   SELECT 'zz' FROM dual
);

Не уверен, если это вам поможет.

Для <<21 > Oracle использует только последовательность. И варианты на общей последовательности также применяются к этому.

NEXTVAL используется для извлечения следующей доступной последовательности, и, очевидно, это псевдокоманда.

Ниже приведено Oracle

Вы не можете использовать CURRVAL и NEXTVAL в следующих конструкциях:

  • Подзапрос в инструкции DELETE, SELECT или UPDATE
  • Запрос представления или материализованного представления
  • Оператор SELECT с оператором DISTINCT
  • Оператор SELECT с предложением GROUP BY или предложением ORDER BY
  • Оператор SELECT, который объединен с другим оператором SELECT с оператором UNION, INTERSECT или MINUS
  • Предложение WHERE оператора SELECT
  • Значение DEFAULT для столбца в инструкции CREATE TABLE или ALTER TABLE
  • Условие ограничения CHECK

Правило операций subquery и SET выше должно ответить на ваш вопрос.

И по причине NULL, когда pseudocolumn (например, NEXTVAL) используется с операцией SET или любыми другими правилами, упомянутыми выше, вывод является NULL, так как Oracle не может извлечь их с помощью объединения нескольких выборок.

Посмотрим ниже запрос

select rownum from dual
union all 
select rownum from dual

результат

ROWNUM
1
1