【问题标题】:ORA-02292"integrity constraint violated -ORA-02292“违反完整性约束 -
【发布时间】:2016-04-13 19:49:37
【问题描述】:

我有一个应用程序应该从订单表中删除订单并将已删除订单的详细信息插入到两个表中:一个包含订单的详细信息,第二个包含订单的详细信息。问题来自表 DELETE_ORDERS_D,因为它引发了以下异常:

        02292. 00000 - "integrity constraint (%s.%s) violated - child record  
                        found"
        *Cause:    attempted to delete a parent key value that had a foreign
                        dependency.

订单

      create table orders (
       ono      number(5) not null primary key,
       cno      number(5) references customers,
       eno      number(4) references employees,
       received date,
       shipped  date);

订单详情

     create table odetails (
     ono      number(5) not null references orders,
     pno      number(5) not null references parts,
     qty      integer check(qty > 0),
     primary key (ono,pno));

零件

     create table parts(
     pno      number(5) not null primary key,
     pname    varchar2(30),
     qoh      integer check(qoh >= 0),
     price    number(6,2) check(price >= 0.0),
     olevel   integer);

样本数据

     insert into orders values
       (1020,1111,1000,'10-DEC-11','12-DEC-11');
     insert into orders values
       (1021,1111,1000,'12-JAN-12','15-JAN-12');
     insert into orders values
       (1022,2222,1001,'13-FEB-12','20-FEB-12');
     insert into orders values
       (1023,3333,1000,'12-MAR-12',null);
     insert into odetails values
       (1020,10506,1);
     insert into odetails values
       (1020,10507,1);
     insert into odetails values
       (1020,10508,2);
     insert into odetails values
       (1020,10509,3);
     insert into odetails values
       (1021,10601,4);
     insert into odetails values
       (1022,10601,1);
     insert into odetails values
       (1022,10701,1);
     insert into odetails values
       (1023,10800,1);
     insert into odetails values
       (1023,10900,1);
     insert into parts values
       (10506,'Land Before Time I',200,19.99,20);
    insert into parts values
       (10507,'Land Before Time II',156,19.99,20);
    insert into parts values
       (10508,'Land Before Time III',190,19.99,20); 
    insert into parts values
       (10509,'Land Before Time IV',60,19.99,20);
    insert into parts values
       (10601,'Sleeping Beauty',300,24.99,20);
    insert into parts values
       (10701,'When Harry Met Sally',120,19.99,30);
    insert into parts values
       (10800,'Dirty Harry',140,14.99,30);
    insert into parts values
       (10900,'Dr. Zhivago',100,24.99,30);

表格生成错误如下

    CREATE TABLE DELETE_ORDERS_D (
       ONO      number(5) not null references orders,
       PNO      number(5) not null references parts,
       QTY     integer check(qty > 0),
       CONSTRAINT DEL_ODETAILS_pk PRIMARY KEY (ONO,PNO));

约束优化问题

select * from all_constraints
     where owner = 'SCOTT'
     and constraint_name = 'SYS_C007539';


          CONSTRAINT_TYPE           TABLE_NAME                
        ------------------        -----------------
                R                  DELETE_ORDERS_D

你能帮我解决这个问题吗!

【问题讨论】:

  • 你能实际显示你使用的删除命令吗?
  • 我将订单号传递给删除订单和订单详细信息的过程,并将它们的详细信息插入到两个不同的表中,其中一个是 Delete_orders_D。程序太长,无法发布问题!
  • 好吧,如果没有实际引发此错误的代码,除了猜测之外,没有人能给出答案。尽管错误非常简单,但在您的过程中的某处,您正试图删除 DELETE_ORDERS_D 上的订单或部件上的注册表,
  • 您好 Jorge,感谢您的帮助,如果我们可以打开一个聊天室,然后我可以将程序发送给您,会更好吗?但是,如果我发布程序,它看起来不会很好,因为它太长了!
  • 不需要(您对 Bob 的回答的评论提供了线索)。我建议您在 (1020,1021,1022,1023) 中 ONO 的 DELETE_ORDERS_D 表上运行选择命令,看看那里是否有注册表。如果是,这是您的问题,您必须查看您的程序并在删除订单表之前执行此检查。请注意,由于您的示例数据,我建议了这些 ID,它可能是其他 ID。我建议您查看您的程序并获取订单表上发生删除的行并将其添加到您的问题中,前后几行。不需要整个代码。

标签: sql oracle oracle11g


【解决方案1】:

历史表(例如 DELETE_ORDERS_D)不能有引用实际数据表(在本例中为 ORDERS 和 PARTS)的外键约束,因为当您删除 ORDERS 和 PARTS 中的相应行时,它会准确地导致您遇到的错误看到。删除 DELETE_ORDERS_D.ONO 和 PNO 上的外键约束。

祝你好运。

【讨论】:

  • 感谢您的帖子。删除将仅在 ORDERS 和 ODETAILS 表上。我将确保按照您的建议更改表格并删除 FK。但是,我是否需要将 DELETE_ORDERS_D 的主键保留为 (ono, pno)?
  • 我不会建议这样的事情,如果表被设计成有这个约束,那就是保持一致性,删除它会在数据库中留下不一致的数据。
  • 很抱歉我误解了你的意思!你能告诉我你到底是什么原因导致我迷路了!
  • 如果 (ONO, PNO) 始终是唯一的,则保留 (ONO, PNO) 的主键。 @JorgeCampos - 我对这种情况的理解是,OP 正在使用 DELETE_ORDERS_D 表来跟踪已从 ORDERS、PARTS 和 ODETAILS 表中删除的行。由于 DELETE_ORDERS_D 表的目的是跟踪主表中不再存在的数据,因此您不能很好地将外键约束返回到 ORDERS 和 PARTS,因为 DELETE_ORDERS_D 的目的是记录已被从这些表中删除。谢谢。
  • @JorgeCampos - 因为在问题中显示的CREATE TABLE 语句中没有命名约束,并且因为我没有方便测试的 Oracle 实例,所以我不觉得相信我可以创建一个ALTER TABLE,它实际上会正确地删除约束。我知道我可以查询ALL_CONSTRAINTSALL_CONS_COLUMNS 来确定约束名称,但正如我所说的无法测试我怀疑我是否会做对。谢谢。
【解决方案2】:

如果您遇到此类错误,请使用以下查询找到必须首先删除的表:

 SELECT * FROM dba_constraints
 WHERE constraint_name = 'FK_WMINVN_LOCNHDR'; 

【讨论】:

    【解决方案3】:

    正如 bob jarvis 之前所说,历史表不应该有引用实际数据的约束。

    但是,要解决您的问题,您可以编写 on delete cascade 以及您的外键约束。每当您在父表上发出删除记录时,这将自动删除与其关联的所有子记录

    更改odetails 上的外键约束。但为此,您需要删除 odetails 表中现有的外键约束。

    alter table odetails add constraint odetails_ono_fk
    foreign key (ono) references orders(ono) on delete cascade;
    

    【讨论】:

    • 感谢您的回答。我无法更改表 Odetails,因为我在创建架构之前添加了 DELETE_ORDERS_D!这将改变表格之间的建模关系!
    • @Dawn:如果我正确阅读了问题,DELETE_ORDERS_D 的目的是维护已删除的订单和部件的记录,在这种情况下,删除级联将删除 OP 希望的记录保存。也许我误解了这一点,但这是我的理解。谢谢。
    猜你喜欢
    • 2020-04-08
    • 2017-05-17
    • 2019-03-16
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 2019-08-06
    • 2019-12-31
    • 2014-06-07
    相关资源
    最近更新 更多