2017-12-21 31 views
2
DB2에서

사이의 외래 키 제약은, 내가 3 개 테이블이 있다고 가정 DB2 : T1, T2, T3 : 여러 테이블

CREATE TABLE T1 (
    T1_ID INTEGER NOT NULL, 
    PRIMARY KEY (ID) 
); 

CREATE TABLE T2 (
    T2_T1 INTEGER NOT NULL, -- parent entity ID from T1 
    T2_ID INTEGER NOT NULL, 
    PRIMARY KEY (T2_T1, T2_ID), 
); 

CREATE TABLE T3 (
    T3_T1 INTEGER NOT NULL, -- parent entity ID from T1 
    T3_T2 INTEGER NOT NULL, -- parent entity ID from T2 
    T3_ID INTEGER NOT NULL, 
    PRIMARY KEY (T3_T1, T3_T2, T3_ID) 
); 

나는 그것이 기록의 삭제를 금지 할 수있는 방법에 FK 관계를 정의하고 싶습니다 T2에서 연결된 레코드가 T3에 있지만 동시에 T1에서 레코드를 삭제하면 T2와 T3의 레코드가 자동으로 삭제됩니다.

이러한 요구 사항을 충족시키기 위해 FK 제약 조건 만 정의 할 수 있습니까? 또는 T3에서 적절한 레코드 레코드를 먼저 삭제 한 다음 T2에서 T1 이후의 레코드 만 삭제하는 코드를 작성하지 않아도됩니다.

업데이트 : 나는 실행하기 위해 노력하고있어 실제 DB2 10.5 코드 :

CREATE TABLE t1 (
    t1_id INTEGER NOT NULL, 
    PRIMARY KEY(t1_id) 
) 

CREATE TABLE t2 (
    t2_t1 INTEGER NOT NULL, 
    t2_id INTEGER NOT NULL, 
    PRIMARY KEY (t2_t1, t2_id), 
    CONSTRAINT t2_fk_t1 
    FOREIGN KEY (t2_t1) 
    REFERENCES t1 (t1_id) 
    ON DELETE CASCADE 
) 

CREATE TABLE t3 (
    t3_t1 INTEGER NOT NULL, 
    t3_t2 INTEGER NOT NULL, 
    t3_id INTEGER NOT NULL, 
    PRIMARY KEY (t3_t1, t3_t2, t3_id), 
    CONSTRAINT t3_fk_t1 
    FOREIGN KEY (t3_t1) 
    REFERENCES t1 (t1_id) 
    ON DELETE CASCADE, 
    CONSTRAINT t3_fk_t2 
    FOREIGN KEY (t3_t1, t3_t2) 
    REFERENCES t2 (t2_t1, t2_id) 
    ON DELETE RESTRICT 
) 

마지막 CREATE 문은 다음과 같은 오류와 함께 실패는 :

SQL20255N FOREIGN KEY "T3_FK_T2" is not valid because it would cause a descendent table "S.T3" to be delete-connected to its ancestor table "S.T1" through multiple relationships with conflicting delete rules. The conflict is between the delete rules of constraints "S.T3.T3_FK_T1" and "S.T3.T3_FK_T2" on the descendent table. Reason code = "3". SQLSTATE=42915

+0

네, 가능할 수 있습니다 ***** 경고 ***** FK 캐스케이드가 잘못된 경우 DB에 심각한 캐스케이드 오류가 발생하고 행이 부모 및 자식 테이블에서 모두 삭제됩니다. 이를 수행하는 안전한 방법은 restrict를 지정하는 것입니다. 외래 키로 각 ​​테이블의 레코드를 수동으로 훨씬 더 안전하게 삭제해야합니다. ***** 그림 그리기 시작 ****** – danny117

답변

0

이 작동합니다. 조금이라도 이상한 것 같아도, 이 중복되어 개의 제약이있는 것은 금지되어 있지 않습니다.


CREATE TABLE t1 (
    t1_id INTEGER NOT NULL PRIMARY KEY 
); 

CREATE TABLE t2 (
    t2_t1 INTEGER NOT NULL REFERENCES t1(t1_id) ON DELETE CASCADE 
    , t2_id INTEGER NOT NULL 
    , PRIMARY KEY (t2_t1, t2_id) 
); 

CREATE TABLE t3 (
    t3_t1 INTEGER NOT NULL REFERENCES t1(t1_id) ON DELETE CASCADE 
    , t3_t2 INTEGER NOT NULL 
     , FOREIGN KEY (t3_t1,t3_t2) REFERENCES t2(t2_t1,t2_id) ON DELETE RESTRICT 
    , t3_id INTEGER NOT NULL 
     , PRIMARY KEY (t3_t1, t3_t2, t3_id) 
); 
INSERT INTO t1 (t1_id) VALUES (11), (12),(13), (14), (15); 
INSERT INTO t2 (t2_t1,t2_id) VALUES (11, 21), (12,22),(13,23), (14,24), (15,25); 
INSERT INTO t3 (t3_t1,t3_t2,t3_id) VALUES (11, 21,31), (12,22,32),(13,23,33), (14,24,34), (15,25,35); 


DELETE FROM t1 WHERE t1_id = 13; -- should succeed 
DELETE FROM t2 WHERE t2_id = 24; -- should fail 

SELECT * FROM t1; 
SELECT * FROM t2; 
SELECT * FROM t3; 
0

는 네, 가능합니다.

T3에서 T2까지 외래 키를 만들고 T1은 삭제시 RESTRICT이고 T1은 아무런 조치도 취하지 않습니다.

T1에서 외부 키인 캐스케이드 삭제.

CREATE TABLE T1 (
    T1_ID INTEGER NOT NULL unique, 
    PRIMARY KEY (T1_ID) 
); 

CREATE TABLE T2 (
    T2_T1 INTEGER NOT NULL  constraint t2_t1_t1_id_fk 
      references t1 
       on delete cascade, -- parent entity ID from T1 
    T2_ID INTEGER NOT NULL unique, 
    PRIMARY KEY (T2_T1, T2_ID) 
); 

CREATE TABLE T3 (
    T3_T1 INTEGER NOT NULL constraint t3_t1_t1_id_fk 
     references t1 
      on delete cascade, -- parent entity ID from T1 
    T3_T2 INTEGER NOT NULL constraint t3_t2_t2_id_fk 
     references t2 (t2_id) on delete restrict, -- parent entity ID from T2 
    T3_ID INTEGER NOT NULL, 
    PRIMARY KEY (T3_T1, T3_T2, T3_ID) 
); 

더 엄격한 외래 키를 사용하려는 경우 다른 관점에서 간단히 수행 할 수 있습니다. (ID에서 참조 번호에 이르는 외래 키!)

최악의 시나리오 항상 트리거가 존재하므로 모든 것이 가능합니다. :)

+0

DB2 10.5에서이 작업을 시도하고 있으며 "삭제 규칙 충돌"로 T3를 정의 할 수 없습니다 ... – faraway

+0

오 이런. DB2를 슬프게 사용하지 않았고, 개인적으로 PostgreSQL을 사용합니다. 경우에 따라 전체 작성 스크립트로 내 대답을 편집했습니다. –

+0

죄송합니다. 원본 게시물을 명시해야하며 지금 업데이트됩니다. – faraway