级联/删除

时间:2016-06-09 14:04:52

标签: oracle

我有一张表,其中包含来自多个表的“附件列表”。当我删除主表中的主键时,它应该删除enrollid。如果我有一个主表和一个从表,这是真的。但是,如果我有多个主表并且想要实现级联删除,则会抛出违反主键和外键的错误消息。因为附件表中的enrollid不在表1和表2中。

有没有办法在此实现级联,或者我在删除表1和表2中的enrollid时在附件中使用常规删除方法。

表:附件 enrollid int - 这是外键 attachmentname varchar2(50)

主表1:department1 enrollid int - 这是主键 departmentname varchar2(25)

主表2:department2 enrollid int - 这是主键 departmentadd varchar2(25)

提前感谢您的帮助。

使用要插入的某些数据创建语句。

CREATE TABLE DEPARTMENT
   (    
   ENROLLID NUMBER, 
     DEPARTNAME VARCHAR2(100), 
     CONSTRAINT DEPARTMENT_PK PRIMARY KEY (ENROLLID)
   ) ;   

   INSERT INTO DEPARTMENT (ENROLLID, DEPARTNAME) VALUES (1, 'DEPART1');
   INSERT INTO DEPARTMENT (ENROLLID, DEPARTNAME) VALUES (2, 'DEPART2');

CREATE TABLE DIVISION
   (    
   ENROLLID NUMBER, 
     DIVISIONNAME VARCHAR2(100), 
     CONSTRAINT DIVISION_PK PRIMARY KEY (ENROLLID)
   );       

   INSERT INTO DIVISION (ENROLLID, DIVISIONNAME) VALUES (3, 'DIV1');
   INSERT INTO DIVISION (ENROLLID, DIVISIONNAME) VALUES (4, 'DIV2');


  CREATE TABLE ATTACHMENTS 
   (    
     ENROLLID NUMBER, 
     FILENAME VARCHAR2(500), 
     CONSTRAINT ATTACHMENTS_FK FOREIGN KEY (ENROLLID)
      REFERENCES Department(ENROLLID) ON DELETE CASCADE
      --REFERENCES DIVISION(ENROLLID) ON DELETE CASCADE
   ) 

   the above sql creates the table with foreign key constraint. but, it throws error message if include the second CASCADE statement. So, i commented the second reference. Then, i ran the below INSERT statements. The first two were inserted fine. third line threw an error message (ORA-02291  Integrity constraint violated - parent key not found).

   INSERT INTO ATTACHMENTS (ENROLLID,FILENAME) VALUES (1, 'attachment1'); 
   INSERT INTO ATTACHMENTS (ENROLLID,FILENAME) VALUES (2, 'attachment1');
   INSERT INTO ATTACHMENTS (ENROLLID,FILENAME) VALUES (3, 'attachment1');
   INSERT INTO ATTACHMENTS (ENROLLID,FILENAME) VALUES (4, 'attachment1')

1 个答案:

答案 0 :(得分:0)

为了实现您的目标,我认为您需要在附件表和部门和部门表之间添加一个附加表。

这样的事情,也许是:

create table department
   (dept_id number, 
    departname varchar2(100), 
    constraint department_pk primary key (dept_id)
    ) ;   

   insert into department (dept_id, departname) values (1, 'DEPART1');
   insert into department (dept_id, departname) values (2, 'DEPART2');

create table division
   (div_id number, 
    divisionname varchar2(100), 
    constraint division_pk primary key (div_id)
   );       

   insert into division (div_id, divisionname) values (1, 'DIV1');
   insert into division (div_id, divisionname) values (2, 'DIV2');

create table enrollment
   (enrollid number,
    dept_id number,
    div_id number,
    constraint enrollment_pk primary key (enrollid),
    constraint enrollment_dept_fk foreign key (dept_id) references department (dept_id),
    constraint enrollment_div_fk foreign key (div_id) references division (div_id),
    constraint enrollment_chk check (div_id is not null or dept_id is not null));

--- here, I have assumed that at least one of div_id and dept_id is populated.
--- If it should be that only one of them can be populated, not both, then you'll need to change the check constraint accordingly.


insert into enrollment (enrollid, dept_id, div_id) values (1, 1, null);
insert into enrollment (enrollid, dept_id, div_id) values (2, 2, null);
insert into enrollment (enrollid, dept_id, div_id) values (3, null, 1);
insert into enrollment (enrollid, dept_id, div_id) values (4, null, 2);

create table attachments 
   (    
     enrollid number, 
     filename varchar2(500), 
     constraint attachments_fk foreign key (enrollid)
     references enrollment (enrollid) on delete cascade
   );

   insert into attachments (enrollid,filename) values (1, 'attachment1'); 
   insert into attachments (enrollid,filename) values (2, 'attachment2');
   insert into attachments (enrollid,filename) values (3, 'attachment3');
   insert into attachments (enrollid,filename) values (4, 'attachment4');

   commit;

然后,当您从注册表中删除时,您可以看到该行会自动从附件表中删除。

delete from enrollment where enrollid = 4;

commit;

select * from enrollment order by enrollid;

  ENROLLID    DEPT_ID     DIV_ID
---------- ---------- ----------
         1          1           
         2          2           
         3                     1

select * from attachments order by enrollid;

  ENROLLID FILENAME
---------- -----------
         1 attachment1
         2 attachment2
         3 attachment3