Oracle 12 c: вставить в таблицу со столбцом идентификаторов - PullRequest
3 голосов
/ 08 мая 2020

У меня есть таблица с одним столбцом типа Identity Column, который также является первичным ключом.

CREATE  TABLE identity_demo  (
    id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
    description VARCHAR2(100) not null
  );

тогда я вставляю несколько строк данных

insert into identity_demo (id, description) values (1,'A');
insert into identity_demo (id, description) values (2,'B');
insert into identity_demo (id, description) values (3,'C');
insert into identity_demo (id, description) values (4,'D');
insert into identity_demo (id, description) values (5,'E');
insert into identity_demo (id, description) values (6,'F');

, если я теперь хочу вставить строку, для которой идентификатор значения не установлен, я получаю нарушение ключа

insert into identity_demo (description) values ('G');

ORA-00001: Unique Constraint (UWE.IDENTITY_DEMO_PK) verletzt, что лучше всего продолжить здесь?

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Прежде всего, кажется, что в конец DDL создания таблицы добавлена ​​часть , CONSTRAINT IDENTITY_DEMO_PK PRIMARY KEY (id)

.

Просто удалите часть BY DEFAULT ON NULL, чтобы оставить управление генерация идентификатора в СУБД с сохранением столбца ID как PRIMARY KEY. В этом случае вы должны удалить столбец ID из списка столбцов в инструкции Insert, как в

INSERT INTO identity_demo (description) VALUES ('G');:

SQL> CREATE  TABLE identity_demo  (
  2      id          NUMBER GENERATED AS IDENTITY,
  3      description VARCHAR2(100) NOT NULL,
  4      CONSTRAINT IDENTITY_DEMO_PK PRIMARY KEY (id)
  5    );

Table created

SQL> BEGIN
  2    INSERT INTO identity_demo (id, description) VALUES (1,'A');
  3    INSERT INTO identity_demo (id, description) VALUES (2,'B');
  4    INSERT INTO identity_demo (id, description) VALUES (3,'C');
  5    INSERT INTO identity_demo (id, description) VALUES (4,'D');
  6    INSERT INTO identity_demo (id, description) VALUES (5,'E');
  7    INSERT INTO identity_demo (id, description) VALUES (6,'F');
  8  END;
  9  /

ORA-32795: cannot insert into a generated always identity column
ORA-06512: at line 3

SQL> INSERT INTO identity_demo (description) VALUES ('G');

1 row inserted

SQL> SELECT * FROM identity_demo;

        ID DESCRIPTION
---------- -------------------------------------------------------
         1 G

SQL> BEGIN
  2    INSERT INTO identity_demo (description) VALUES ('A');
  3    INSERT INTO identity_demo (description) VALUES ('B');
  4    INSERT INTO identity_demo (description) VALUES ('C');
  5    INSERT INTO identity_demo (description) VALUES ('D');
  6    INSERT INTO identity_demo (description) VALUES ('E');
  7    INSERT INTO identity_demo (description) VALUES ('F');
  8  END;
  9  /

PL/SQL procedure successfully completed

SQL> SELECT * FROM identity_demo;

        ID DESCRIPTION
---------- --------------------------------------------------------
         1 G
         2 A
         3 B
         4 C
         5 D
         6 E
         7 F

7 rows selected
0 голосов
/ 11 мая 2020

У вас есть конфликт между значениями идентичности, которые вы вставили вручную (от 1 до 6), и значением идентичности, созданным генератором последовательности. Вы можете исправить это, настроив генератор последовательности:

ALTER TABLE identity_demo MODIFY (
  id GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH LIMIT VALUE));

START WITH LIMIT VALUE блокирует таблицу, находит самый высокий идентификатор и устанавливает внутренний генератор последовательности на следующее более высокое значение 7.

Если вы не хотите запускать эту ALTER TABLE команду, вы можете разделить числовые пробелы, скажем, 1 ... 999 для ручных значений и 1000 ... для автоматических c значений. Вы должны настроить свой генератор следующим образом:

ALTER TABLE identity_demo MODIFY (
  id GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1000));

INSERT INTO identity_demo (description) VALUES ('H');

...
6      F
7      G
1000   H
...