Невозможно ввести данные в таблицы с взаимосвязанными внешними ключами - PullRequest
0 голосов
/ 04 мая 2020

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

CREATE TABLE Employee(
Ssn VARCHAR(10) PRIMARY KEY NOT NULL,
BDate DATE,
FName VARCHAR(25),
MInit VARCHAR(5),
LName VARCHAR(25),
Address VARCHAR(40),
Sex VARCHAR(6),
Salary INT,
SupervisorSsn VARCHAR(10),
DNumber INT
);
CREATE TABLE

CREATE TABLE Department(
DNumber INT PRIMARY KEY NOT NULL,
DName VARCHAR(15),
MgrSsn VARCHAR(10),
MgrStartDate DATE,
NumberofEmployees INT,
CONSTRAINT Department_MgrSsn_FK FOREIGN KEY(MgrSsn) REFERENCES Employee(Ssn) ON DELETE SET DEFAULT ON UPDATE CASCADE
);

ALTER TABLE Employee
ADD CONSTRAINT Employee_SupervisorSsn_FK FOREIGN KEY(SupervisorSsn) REFERENCES Employee(Ssn) ON DELETE SET DEFAULT ON UPDATE CASCADE,
ADD CONSTRAINT Employee_DNumber_FK FOREIGN KEY(DNumber) REFERENCES Department(DNumber) ON DELETE SET DEFAULT ON UPDATE CASCADE;

1 Ответ

0 голосов
/ 04 мая 2020

Есть несколько способов сделать это в Postgres.

Обновление позже

Самый очевидный: вставьте null значения параметров, а затем обновите его позже:

insert into department 
  (dnumber, dname)
values 
  (1, 'One'),
  (2, 'Two'),
  (3, 'Three');

insert into employee (ssn, fname, lname, supervisorssn, dnumber)
values 
  ('123', 'Arthur', 'Dent', '456', 1),
  ('456', 'Ford', 'Prefect', null, 2),
  ('789', 'Zaphod', 'Beeblebrox', null, 3);

update department
  set mgrssn = '456'
where dnumber in (1,2);

update department
  set mgrssn = '789'
where dnumber = 3;

Онлайн пример

Отложенные ограничения

Сделайте ограничения отложенными, чтобы они проверялись в конце транзакции, а не при выполнении INSERT:

ALTER TABLE department
  add constraint fk_dempt2emp foreign key (mgrssn) references employee
  deferrable initially deferred; --<<

Затем вы можете вставить строки в любом порядке, который вам нравится, если все происходит в одной транзакции:

begin transaction; --<< important!

insert into department 
  (dnumber, dname, mgrssn)
values 
  (1, 'One', '456'),
  (2, 'Two', '456'),
  (3, 'Three', '789')

insert into employee (ssn, fname, lname, supervisorssn, dnumber)
values 
  ('123', 'Arthur', 'Dent', '456', 1),
  ('456', 'Ford', 'Prefect', null, 2),
  ('789', 'Zaphod', 'Beeblebrox', null, 3);

commit; -- the FKs will be checked here

Делайте все в одном выражении

Вы можете использовать , модифицируя данные CTE вставить строки в две таблицы. Поскольку это оценивается как один оператор, ограничения не нужно откладывать.

with new_depts as (
  insert into department 
    (dnumber, dname, mgrssn)
  values 
    (1, 'One', '456'),
    (2, 'Two', '456'),
    (3, 'Three', '789')
)
insert into employee (ssn, fname, lname, supervisorssn, dnumber)
values 
  ('123', 'Arthur', 'Dent', '456', 1),
  ('456', 'Ford', 'Prefect', null, 2),
  ('789', 'Zaphod', 'Beeblebrox', null, 3)
;

Онлайн пример

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