Postgresql
插入數據違反外鍵約束
考慮一下我有兩個表
Employee
和Department
下面給出的欄位:員工:
Fname、Minit、Lname、*
Ssn
*Bdate、地址、性別、薪水、Super_ssn、Dno部:
Dname
,Dnumber
, Mgr_ssn, Mgr_start_date*
Italics and code block
*表示表的主鍵。在上述情況下,Super_Ssn引用員工的SSN,而Dno引用部門的Dnumber。為它們創建 sql 非常簡單,首先添加列,然後在形成兩個表時更改它們。但是,在插入數據時,如下所示:
insert into employee values('James','E','Borg','888665555','1937-11-10','asda','M',55000,NULL,1); ERROR: insert or update on table "employee" violates foreign key constraint "dno_ref_dnum_dpt" DETAIL: Key (dno)=(1) is not present in table "department".
和
insert into sp0090.department values ('Headquarter',1,'888665555','1981-06-19'); ERROR: insert or update on table "department" violates foreign key constraint "department_mgr_ssn_fkey" DETAIL: Key (mgr_ssn)=(888665555) is not present in table "employee".
我違反了外鍵約束。這可以追溯,因為要在部門中插入****Mgr_ssn,它必須存在於 Employee 中,而要在 Employee 中插入dno,它****必須存在於部門中。但是,我需要按照原樣維護模式來填充表。如何解決這個循環引用?謝謝。
在 Postgres 中,有兩種方法可以避免插入帶有循環引用的表的先有雞還是先有蛋的問題。
a) 延遲其中一個約束,要麼將其聲明為
DEFERRABLE INITIALLY DEFERRED
創建時,要麼聲明為DEFERRABLE
已創建,然後在需要時將其延遲。有關使用可延遲約束的範例,請參閱我在此問題中的回答:
b) 使用單個語句插入兩個(或更多)表,使用修改 CTE。您的案例範例:
with insert_emp as ( insert into employee (Fname, Minit, Lname, Ssn, Bdate, Address, Sex, Salary, Super_ssn, Dno) values ('James', 'E', 'Borg', '888665555', '1937-11-10', 'asda', 'M', 55000, NULL, 1) returning * ), insert_dep ( insert into sp0090.department (Dname, Dnumber, Mgr_ssn, Mgr_start_date) values ('Headquarter', 1, '888665555', '1981-06-19') returning * ) select * from insert_emp as e full join insert_dep as d on e.dno = d.dnumber and e.ssn = d.mgr_ssn ;
有一篇舊文章解釋了這種情況,這稱為循環引用。從兩個表中插入或刪除行時,您將遇到“雞和蛋”問題。我應該先插入哪個表 - 不違反任何約束?我建議閱讀下面的這篇文章,看看它是否有幫助。