Postgresql

插入數據違反外鍵約束

  • December 1, 2016

考慮一下我有兩個表EmployeeDepartment下面給出的欄位:

員工:

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已創建,然後在需要時將其延遲。

有關使用可延遲約束的範例,請參閱我在此問題中的回答:

在 SQL 中實現具有總參與約束的多對多關係。

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 ;

有一篇舊文章解釋了這種情況,這稱為循環引用。從兩個表中插入或刪除行時,您將遇到“雞和蛋”問題。我應該先插入哪個表 - 不違反任何約束?我建議閱讀下面的這篇文章,看看它是否有幫助。

SQL 設計:循環參考

引用自:https://dba.stackexchange.com/questions/152427