Создайте две таблицы, внешние ключи которых ссылаются друг на друга - PullRequest
0 голосов
/ 08 октября 2019

В Oracle SQL, SQL Developer: я пытаюсь создать две таблицы, каждая из которых имеет внешний ключ, который ссылается на первичный ключ другой таблицы.

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

Вот общее представление о том, как я его структурирую:

CREATE TABLE table1 
(
    column1 datatype PRIMARY KEY NOT NULL,
    column2 datatype NOT NULL,
    column3 datatype NOT NULL,

    CONSTRAINT fk_keyname 
        FOREIGN KEY (colmn3)
        REFERENCES otherTable (column3)
);

CREATE TABLE table2 
(
    column1 datatype PRIMARY KEY NOT NULL,
    column2 datatype NOT NULL,
    column3 datatype NOT NULL,

    CONSTRAINT fk_keyname2
        FOREIGN KEY (colmn3)
        REFERENCES otherTable2 (column3)
);

Я получаю ошибку

ORA-00942: таблица или представление делаетне существует

Я исправил это раньше, сначала создав родительскую таблицу, но, поскольку они оба ссылаются друг на друга, я в растерянности, потому что я ДОЛЖЕН делать здесь, потому что ДОЛЖЕН БЫТЬ ССЫЛКА КАЖДОГО ДРУГОГО вэто частный случай.

Ответы [ 2 ]

5 голосов
/ 08 октября 2019

Вы можете сначала создать таблицы, а затем FK. Например:

create table table1 (
  column1 int primary key not null,
  column2 int not null,
  column3 int not null
);

create table table2 (
  column1 int primary key not null,
  column2 int not null,
  column3 int not null,
  constraint fk2
    foreign key (column3)
    references table1 (column1)
);

alter table table1 add constraint fk1
   foreign key (column3)
   references table1 (column1);

Даже если таблицы будут созданы, вы не сможете вставить в них данные, так как ограничение не позволит вам создать строку, которая не указывает на другую [несуществующую]] ряд. Чтобы вставить данные, вам нужно создать ограничение как «отложенное». Вот улучшенный SQL-скрипт:

create table table1 (
  column1 int primary key not null,
  column2 int not null,
  column3 int not null
);

create table table2 (
  column1 int primary key not null,
  column2 int not null,
  column3 int not null,
  constraint fk2
    foreign key (column3)
    references table1 (column1) deferrable initially deferred
);

alter table table1 add constraint fk1
   foreign key (column3)
   references table1 (column1) deferrable initially deferred;

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

1 голос
/ 08 октября 2019

С технической точки зрения было бы возможно создать первую таблицу без ограничения внешнего ключа, затем создать вторую таблицу (с внешним ключом) и, наконец, добавить ограничение внешнего ключа в первую таблицу.

Но проблема, с которой вы столкнулись, указывает на проблему дизайна . Он также предопределяет проблему, с которой придется столкнуться, когда вы попытаетесь заполнить таблицы: из-за перекрестных внешних ключей вы не сможете INSERT записей в таблицах, если вы не сделаете некоторые сложные вещи, такие как временное отключение одной изограничение, вставляя в обе таблицы, обновляя первую таблицу, затем включите ограничение.

Ваш вопрос не дает мне достаточного контекста для предложения альтернативного дизайна, но, исходя из опыта, наверняка существует лучшее решение . Это может включать наличие одной таблицы вместо двух (если вы имеете дело с отношением 1-1) или наличие третьей таблицы, которая действует как таблица-мост, если это отношение NM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...