#sql #postgresql
#sql #postgresql
Вопрос:
CREATE TABLE public.impiegato(
CF varchar NOT NULL,
codice_reparto int4 NOT NULL,
mansione varchar NULL,
CONSTRAINT impiegato_pkey PRIMARY KEY (CF),
CONSTRAINT impiegato_fkey FOREIGN KEY (codice_reparto) REFERENCES reparto(codice),
);
CREATE TABLE public.reparto(
codice int4 NOT NULL,
nome varchar NULL,
cf_responsabile varchar NULL,
nome_responsabile varchar NULL UNIQUE,
CONSTRAINT reparto_pkey PRIMARY KEY (codice),
CONSTRAINT reparto_cf_responsabile_fkey FOREIGN KEY (cf_responsabile) REFERENCES impiegato(CF)
);
Когда я запускаю код sql, он сообщает мне, что таблица impiegato не существует. Могу ли я запустить внешний ключ для первичного ключа другой таблицы?
Ответ №1:
Таблица, на которую ссылается ссылка, должна существовать при объявлении внешнего ключа.
Поскольку в вашем случае две таблицы ссылаются друг на друга, решить эту проблему, просто создав сначала нужную, невозможно.
Сначала вы должны создать первый (любой из них) без ограничения внешнего ключа, создать второй, а затем добавить ограничение внешнего ключа к первому.
Что-то вроде:
CREATE TABLE public.impiegato
(cf varchar
NOT NULL,
codice_reparto int4
NOT NULL,
mansione varchar
NULL,
CONSTRAINT impiegato_pkey
PRIMARY KEY (cf));
CREATE TABLE public.reparto
(codice int4
NOT NULL,
nome varchar
NULL,
cf_responsabile varchar
NULL,
nome_responsabile varchar
NULL
UNIQUE,
CONSTRAINT reparto_pkey
PRIMARY KEY (codice),
CONSTRAINT reparto_cf_responsabile_fkey
FOREIGN KEY (cf_responsabile)
REFERENCES impiegato
(cf));
ALTER TABLE public.impiegato
ADD CONSTRAINT impiegato_fkey
FOREIGN KEY (codice_reparto)
REFERENCES reparto
(codice);
К сожалению, вы не пометили свою СУБД. Из некоторых деталей я предположил, что это может быть Postgres, а приведенный выше код, следовательно, является кодом Postgres. Если вы не используете Postgres, вам может потребоваться адаптировать ALTER TABLE
инструкцию, они могут отличаться в разных СУБД.
Комментарии:
1. заправьте вас. Но как добавить данные в эту таблицу? Когда я добавляю данные, Postgres не работают
2. @ElenaRondina: На самом деле это другой вопрос, я думаю, он решаем. Но какой-то указатель: либо а) сначала вставьте в
reparto
сNULL
помощью forcf_responsabile
, в конце концов, он определен для разрешенияNULL
s , затем вставьте вimpiegato
и обновитеreparto
с помощью правильного внешнего ключа. Или б) поиск функции отложенных ограничений, предлагаемых Postgres. Определил ограничения как переносимые и отложил их проверки до конца транзакции, которая вставляет записи.3. Спасибо. Теперь Postgres работает. Мой учитель дал мне странное упражнение: в отделе работают несколько сотрудников, но сотрудник может работать только в одном отделе. Также в отделе может быть только один менеджер (который является сотрудником) Я решил это с помощью таблиц, написанных выше, но я не знаю, правильно ли это. по сути, отдел и сотрудник ссылаются на самих себя. Кстати, спасибо вам
4. @ElenaRondina: В таком сценарии нет ничего странного. К сожалению, я не говорю на (естественном) языке, на котором это написано, поэтому я не использую то, что есть. Но если
reparto
означает отдел,impiegato
означает сотрудника иcf_responsabile
менеджера, то в целом, я думаю, все в порядке. Только еслиnome_responsabile
это имя менеджера, оно не принадлежитreparto
. Имена сотрудников должны храниться только вimpiegato
. Вы можете получить имя менеджера, просмотрев запись там.5. как вы пишете, reparto означает отдел, impiegato означает сотрудника, а cf_responsabile manager . Теперь все работает. Большое вам спасибо 🙂