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

#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 помощью for cf_responsabile , в конце концов, он определен для разрешения NULL s , затем вставьте в impiegato и обновите reparto с помощью правильного внешнего ключа. Или б) поиск функции отложенных ограничений, предлагаемых Postgres. Определил ограничения как переносимые и отложил их проверки до конца транзакции, которая вставляет записи.

3. Спасибо. Теперь Postgres работает. Мой учитель дал мне странное упражнение: в отделе работают несколько сотрудников, но сотрудник может работать только в одном отделе. Также в отделе может быть только один менеджер (который является сотрудником) Я решил это с помощью таблиц, написанных выше, но я не знаю, правильно ли это. по сути, отдел и сотрудник ссылаются на самих себя. Кстати, спасибо вам

4. @ElenaRondina: В таком сценарии нет ничего странного. К сожалению, я не говорю на (естественном) языке, на котором это написано, поэтому я не использую то, что есть. Но если reparto означает отдел, impiegato означает сотрудника и cf_responsabile менеджера, то в целом, я думаю, все в порядке. Только если nome_responsabile это имя менеджера, оно не принадлежит reparto . Имена сотрудников должны храниться только в impiegato . Вы можете получить имя менеджера, просмотрев запись там.

5. как вы пишете, reparto означает отдел, impiegato означает сотрудника, а cf_responsabile manager . Теперь все работает. Большое вам спасибо 🙂