当前位置: 首页 > 知识库问答 >
问题:

Oracle SQL Developer:插入值时违反了完整性约束(未找到父项)

皮自明
2023-03-14

我被要求解决的最初问题是:

创建两个表:Employee:empID(PK)、empFname、empLname、deptID(FK)和Department:deptID(PK)、deptName、chairID。chairID是Employee表中的empID。在Department表中至少插入3行,在Employee表中至少插入6行。更新chairID时创建触发器,强制执行以下业务规则:一名员工只能主持一个部门。每个系只有一把椅子。

我解决这个问题的办法是:

create table Employee(empID NUMBER,
empFname VARCHAR2(20),
empLname VARCHAR2(20),
deptID NUMBER,
PRIMARY KEY (empID)
);

create table Department(deptID NUMBER,
deptName VARCHAR2(20),
chairID NUMBER,
PRIMARY KEY (deptID));

ALTER TABLE Employee
ADD FOREIGN KEY (deptID) REFERENCES Department(deptID);  

ALTER TABLE Department
ADD FOREIGN KEY (chairID) REFERENCES Employee(empID);   


INSERT INTO DEPARTMENT (deptID ,deptName,chairID ) VALUES (401,'COMPUTER SCIENCE',301);
INSERT INTO DEPARTMENT (deptID ,deptName,chairID ) VALUES (402,'ELECTRONICS',302);
INSERT INTO DEPARTMENT (deptID ,deptName,chairID ) VALUES (403,'MATHEMATICS',303);

INSERT INTO EMPLOYEE (empID ,empFname ,empLname,deptID) VALUES (1001,'Alen','Zer',301);
INSERT INTO EMPLOYEE (empID ,empFname ,empLname,deptID) VALUES (1002,'Beny','Ker',301);
INSERT INTO EMPLOYEE (empID ,empFname ,empLname,deptID) VALUES (1003,'Clen','Ler',302);
INSERT INTO EMPLOYEE (empID ,empFname ,empLname,deptID) VALUES (1004,'Dlen','Mer',302);
INSERT INTO EMPLOYEE (empID ,empFname ,empLname,deptID) VALUES (1005,'Elen','Ner',303);
INSERT INTO EMPLOYEE (empID ,empFname ,empLname,deptID) VALUES (1006,'Flen','Oer',303);

CREATE OR REPLACE TRIGGER chairID_after_update
BEFORE UPDATE
ON Department
FOR EACH ROW

DECLARE
v_username varchar2(10);
v_count number;
v_sql varchar2(50);
BEGIN

select count(*) into v_count from Department where chairID = :new.chairID;
IF v_count = 0 then
v_sql := 'alter table set chairID ='+ :new.chairID;
execute immediate v_sql;
end if;

END;
/

我的表创建和触发器编译,但是当试图插入到我的表中时,我所有的插入语句都会命中:

SQL错误: ORA-02291:完整性约束(SYSTEM.SYS_C0010675)违反-找不到父密钥02291. 00000-"完整性约束(%s.%s)违反-找不到父密钥"*原因:外键值没有匹配的主键值。*操作:删除外键或添加匹配的主键。

我应该如何解决此问题?如有任何帮助/建议,将不胜感激。

共有2个答案

单于钊
2023-03-14

一名员工只能主持一个部门。

每个系只有一把椅子。

不需要触发器(除了用于教育目的)-使DEPARTMENT. CHAIRIDUniQUENOTNULL

CREATE TABLE Employee(
  empID    NUMBER
           CONSTRAINT employee__empid__pk PRIMARY KEY,
  empFname VARCHAR2(20),
  empLname VARCHAR2(20),
  deptID   NUMBER       
);

CREATE TABLE Department(
  deptID   NUMBER
           CONSTRAINT department__deptid__pk PRIMARY KEY,
  deptName VARCHAR2(20),
  chairID  NUMBER
           CONSTRAINT department__chairid__nn NOT NULL
           CONSTRAINT department__chairid__u  UNIQUE
           CONSTRAINT department__chairid__fk REFERENCES employee ( empID )
);

ALTER TABLE Employee
ADD CONSTRAINT employee__deptid__fk
    FOREIGN KEY (deptID) REFERENCES Department(deptID);

插入部门ID为NULL的员工,然后创建部门,最后更新员工以包含部门ID:

INSERT INTO EMPLOYEE (empID ,empFname ,empLname,deptID)
  SELECT 1001,'Alen','Zer', NULL FROM DUAL UNION ALL
  SELECT 1002,'Beny','Ker', NULL FROM DUAL UNION ALL
  SELECT 1003,'Clen','Ler', NULL FROM DUAL UNION ALL
  SELECT 1004,'Dlen','Mer', NULL FROM DUAL UNION ALL
  SELECT 1005,'Elen','Ner', NULL FROM DUAL UNION ALL
  SELECT 1006,'Flen','Per', NULL FROM DUAL;

INSERT INTO DEPARTMENT (deptID ,deptName,chairID )
  SELECT 301,'COMPUTER SCIENCE', 1001 FROM DUAL UNION ALL
  SELECT 302,'ELECTRONICS',      1004 FROM DUAL UNION ALL
  SELECT 303,'MATHEMATICS',      1005 FROM DUAL;

MERGE INTO EMLPOYEE dst
USING ( SELECT 301 AS deptid, 1001 AS empID FROM DUAL UNION ALL
        SELECT 301, 1002 FROM DUAL UNION ALL
        SELECT 302, 1003 FROM DUAL UNION ALL
        SELECT 302, 1004 FROM DUAL UNION ALL
        SELECT 303, 1005 FROM DUAL UNION ALL
        SELECT 303, 1006 FROM DUAL ) src
ON ( dst.empId = src.empid )
WHEN MATCHED THEN
  UPDATE SET deptId = src.deptID;
莫兴言
2023-03-14

显然你有一个逻辑问题(循环推理):当没有员工时,你不能先创建一个部门,因为CHAIRID上的外键约束会失败,你不能先创建员工,因为DEPTID上的外键会失败。然而,您的数据模型显然是正确的。

那么,该怎么办?

一种解决方案是不要在一开始就添加外键。执行其他操作,插入数据,然后更改表以添加外键。

一个更好的解决方案是从一开始就添加FK,但使它们可以推迟并在最初推迟。然后插入数据,然后启用FK约束。(实际上,让FK约束可以推迟是个好主意,因为将来你可能会遇到类似的问题,你会欣赏它的灵活性。)

不过,最好的解决方案是创建包含所有约束的表,就像您所做的那样。(请让FK约束可以推迟)。然后插入到DEPARTMENTS中,但保留所有CHAIRIDNULL。然后插入EMPLOYeE行,最后更新DEPARTMENTS行,以显示每个部门的适当主席。

关键是,FK列确实允许NULL——利用这一点打破恶性循环(循环逻辑)。

现在-你的要求是每个部门应该有一个椅子。。。您可以使列CHAIRID不可为空。这将再次阻碍我所描述的计划。仅在INSERT和UPDATE语句之后添加该约束(当然还有触发器)。

 类似资料:
  • 我试图为和创建会话,这两个表都与相同的外键关联到登录表-但是当我为创建种子时,我得到了错误,在我的另一个问题在这个链接中,我没有以最好的方式解释,但得到了一些关于使用(党-角色-关系模型)和这段代码下面他更多的想法有关已解决的问题链接 创建表和主键 创建表和主键 创建表以及主键和外键 使用表为管理员创建会话的过程: 使用表为用户创建会话的过程: 创建管理会话时,我收到一个错误 我做错了什么?

  • SQL数据库代码: 大家好!我做了一系列的桌子,我想我做的每件事都是正确的。除了位置表之外,我在所有表上输入了输入值,没有任何问题。 这就是给我的错误。 第1行错误:ORA-02291:违反完整性约束(ASSIGNMENT.FK_TENANT)-未找到父密钥。 任何帮助和提示将不胜感激。谢谢! 固定的

  • 所以这里是我的数据库: 插入表格: 批次表不断出现的错误是:ORA-02290:违反了检查约束(EJAY.batches\u DATE\u CHK) 学生表出现的错误是:ORA-02291:违反完整性约束-未找到父键 我感到困惑的是,它只显示在表格中的一些行。教职员工和课程都很好,只有这两个。如果答案很明显,我道歉,我是初学者。请帮帮忙

  • 问题内容: 嗨,我正在Oracle SQL开发人员中开发数据库,​​试图从另一个表访问foriegn键。我目前正在使用以下CREATE语句创建的ItemOrdered表 如您所见,我具有以下前键Ords和BeltID。 现在,当我尝试运行以下语句时 它给了我以下错误 违反-找不到父密钥02291。00000-“违反完整性约束(%s。%s)-找不到父密钥” 如果需要,我已经提供了Ords CREAT

  • 我得到了“完整性约束(SYSTEM。FK_FACILITY)违反了父密钥未找到”错误,尽管主键在上一个表中已经明确定义。 我的确切错误是 我只想将值添加到表中,但我无法这样做。。。如果有人能帮我,那就太好了!

  • 我知道,为了在依赖外键的表中插入值,您需要在该表的主键中包含数据。 以下是我的限制: 接下来,我在profs和courses表中插入值: 然后我尝试填充DIDACT表: 但这种情况会发生: 插入didact值('p1','21')错误报告-SQL错误:ORA-02291:违反完整性约束(user.ID\u COURSE\u FK)-未找到父项02291。00000-“违反完整性约束(%s.%s)-