插入数据违反外键约束

Pan*_*ant 6 postgresql foreign-key database-design insert

考虑我有两个表EmployeeDepartment下面给出的字段:

员工:

Fname、Minit、Lname、SsnBdate、地址、性别、薪水、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".
Run Code Online (Sandbox Code Playgroud)

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".
Run Code Online (Sandbox Code Playgroud)

我违反了外键约束。这可以追溯到因为插入Mgr_ssn部门,它必须存在于员工和插入DNO职工它必须存在于部门。但是,我需要按原样维护架构来填充表。我如何解决这个循环引用?谢谢。

ype*_*eᵀᴹ 5

在 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 ;
Run Code Online (Sandbox Code Playgroud)


Jam*_*oat 3

有一篇老文章解释了这种情况,这就是所谓的循环引用。当从两个表中插入或删除行时,您将遇到“先有鸡还是先有蛋”的问题。我应该先插入哪个表 - 在不违反任何约束的情况下?我建议阅读下面这篇文章,看看是否有帮助。

SQL 设计:循环引用