ALTER TABLE 문에 'ON DELETE CASCADE'를 추가하는 방법


130

내 테이블에 외래 키 제약 조건이 있는데 ON DELETE CASCADE를 추가하고 싶습니다.

나는 이것을 시도했다 :

child_table_name 테이블 변경
  구속 조건 수정 fk_name
  외래 키 (child_column_name)
  삭제 계단식에서 parent_table_name (parent_column_name)을 참조합니다.

작동하지 않습니다.

편집 :
외래 키가 이미 존재합니다. 외래 키 열에 데이터가 있습니다.

문을 실행 한 후에 나타나는 오류 메시지 :

ORA-02275 : 이러한 참조 제약이 이미 테이블에 존재합니다

뭐가 문제 야? 진술이 거부되고 삭제가 발생하지 않습니다.
Thorsten

답변:


162

ON DELETE CASCADE기존 구속 조건에 추가 할 수 없습니다 . 당신은해야합니다 drop및 재 create구속을. 문서 것을 보여 MODIFY CONSTRAINT조항 만 수정할 수 있습니다 제약의 상태 (예 : ENABLED/DISABLED...).


86

먼저 drop외국 키와 위의 명령 시도는 넣어 add constraint대신 modify constraint. 이제 이것은 명령입니다 :

ALTER TABLE child_table_name 
  ADD CONSTRAINT fk_name 
  FOREIGN KEY (child_column_name) 
  REFERENCES parent_table_name(parent_column_name) 
  ON DELETE CASCADE;

24
그는 우리에게 postgres와 관련이없는 사람들에게 유리한 장점 인 전체 코드를 제공합니다
Matthis Kohli

1
@WiiMaxx 설립자 질투하는 사람. lol이 답변은 코드도 제공하기 때문에 첫 번째 답변보다 더 중요합니다.
나는 가장 바보 같은 사람입니다.

11

이 PL * SQL은 삭제 캐스케이드가없는 각 제한 조건을 삭제하고 삭제 캐스케이드로 다시 작성하는 스크립트를 DBMS_OUTPUT에 작성합니다.

참고 :이 스크립트의 출력 실행은 사용자의 책임입니다. 결과 스크립트를 읽고 실행하기 전에 편집하는 것이 가장 좋습니다.

DECLARE
      CURSOR consCols (theCons VARCHAR2, theOwner VARCHAR2) IS
        select * from user_cons_columns
            where constraint_name = theCons and owner = theOwner
            order by position;
      firstCol BOOLEAN := TRUE;
    begin
        -- For each constraint
        FOR cons IN (select * from user_constraints
            where delete_rule = 'NO ACTION'
            and constraint_name not like '%MODIFIED_BY_FK'  -- these constraints we do not want delete cascade
            and constraint_name not like '%CREATED_BY_FK'
            order by table_name)
        LOOP
            -- Drop the constraint
            DBMS_OUTPUT.PUT_LINE('ALTER TABLE ' || cons.OWNER || '.' || cons.TABLE_NAME || ' DROP CONSTRAINT ' || cons.CONSTRAINT_NAME || ';');
            -- Re-create the constraint
            DBMS_OUTPUT.PUT('ALTER TABLE ' || cons.OWNER || '.' || cons.TABLE_NAME || ' ADD CONSTRAINT ' || cons.CONSTRAINT_NAME 
                                        || ' FOREIGN KEY (');
            firstCol := TRUE;
            -- For each referencing column
            FOR consCol IN consCols(cons.CONSTRAINT_NAME, cons.OWNER)
            LOOP
                IF(firstCol) THEN
                    firstCol := FALSE;
                ELSE
                    DBMS_OUTPUT.PUT(',');
                END IF;
                DBMS_OUTPUT.PUT(consCol.COLUMN_NAME);
            END LOOP;                                    

            DBMS_OUTPUT.PUT(') REFERENCES ');

            firstCol := TRUE;
            -- For each referenced column
            FOR consCol IN consCols(cons.R_CONSTRAINT_NAME, cons.R_OWNER)
            LOOP
                IF(firstCol) THEN
                    DBMS_OUTPUT.PUT(consCol.OWNER);
                    DBMS_OUTPUT.PUT('.');
                    DBMS_OUTPUT.PUT(consCol.TABLE_NAME);        -- This seems a bit of a kluge.
                    DBMS_OUTPUT.PUT(' (');
                    firstCol := FALSE;
                ELSE
                    DBMS_OUTPUT.PUT(',');
                END IF;
                DBMS_OUTPUT.PUT(consCol.COLUMN_NAME);
            END LOOP;                                    

            DBMS_OUTPUT.PUT_LINE(')  ON DELETE CASCADE  ENABLE VALIDATE;');
        END LOOP;
    end;

11

앞에서 설명한대로 :

ALTER TABLE TABLEName
drop CONSTRAINT FK_CONSTRAINTNAME;

ALTER TABLE TABLENAME
ADD CONSTRAINT FK_CONSTRAINTNAME
    FOREIGN KEY (FId)
    REFERENCES OTHERTABLE
        (Id)
    ON DELETE CASCADE ON UPDATE NO ACTION;

보시다시피 명령을 분리하고 추가해야합니다.


이것은 오라클에 해당되지 않습니다
a_horse_with_no_name

SqlServer에서 방금 테스트되었지만 gopostgres 및 SqlServer 자체에서와 같이 세미콜론 이 발생할 가능성 이 있습니다. 그러나 나머지 핵심 코드는 SQL 표준입니다. 세미콜론으로 테스트하고 방금 변경했습니다
David Silva-Barrera

[이상이 ]표준 SQL (오라클)에 유효하지 않습니다. Oracle은 on update외래 키에 대한 조항 도 지원하지 않습니다 .
a_horse_with_no_name

맞습니다 [ ]. SqlServer와 관련이 있습니다. 좀 더 정리하겠습니다. 정보 on update나에 대해 아무것도 말할 수 없습니다.
David Silva-Barrera

11

MYSQL 사용자를위한 답변 :

ALTER TABLE ChildTableName 
DROP FOREIGN KEY `fk_table`;
ALTER TABLE ChildTableName 
ADD CONSTRAINT `fk_t1_t2_tt`
  FOREIGN KEY (`parentTable`)
  REFERENCES parentTable (`columnName`)
  ON DELETE CASCADE
  ON UPDATE CASCADE;

StackOverflow에 오신 것을 환영합니다. stackoverflow.com/editing-help 에서 코드 형식에 대해 알아보십시오 . 더 읽기 편하도록 코드를 편집했습니다.
Adrian W

3

MySQL을 사용하는 모든 사람 :

당신은 당신에 머리를하면 PHPMYADMIN당신이해야 할 클릭, 당신은 업데이트 할 외래 키가있는 테이블에 웹 페이지 및 탐색 Relational view 에있는 Structure탭과 변경 On delete에 선택 메뉴 옵션을 Cascade.

아래 표시된 이미지 :

여기에 이미지 설명을 입력하십시오


OP는 2009 년에 Oracle 질문에 태그를 추가했으며 PHPMYADMIN은 MySQL 용 타사 소프트웨어 구성 요소입니다.
vegatripy

7
물론 그렇습니다. 그러나이 질문에 대해 Google에서 MySQL 에서이 작업을 수행하는 방법을 알고 싶었고 Google이 저를 데려 왔습니다. 예, 질문에 Oracle 태그가 지정되어 있으므로이 답변은 정확하지 않습니다. 그러나이 답변을 우연히 발견 한 독자와 같은 독자에게는 유용 할 것입니다. 그래서 않습니다 이 오라클 특정하지 않더라도,이 페이지에 가치를 추가 할 수 있습니다. James111 감사합니다!
Mike Gledhill

3

여기에 편리한 해결책이 있습니다! SQL Server 2008 R2를 사용하고 있습니다.

ON DELETE / UPDATE CASCADE를 추가하여 FK 제약 조건을 수정하려면 다음 단계를 수행하십시오.

숫자 1 :

구속 조건을 마우스 오른쪽 버튼으로 클릭하고 수정을 클릭하십시오.

여기에 이미지 설명을 입력하십시오

2 번:

왼쪽에서 구속 조건을 선택하십시오 (둘 이상있는 경우). 그런 다음 오른쪽에서 " INSERT And UPDATE Specification "지점을 축소 하고 규칙 삭제 또는 규칙 업데이트 행에서 필요에 따라 작업을 지정하십시오. 그런 다음 대화 상자를 닫습니다.

여기에 이미지 설명을 입력하십시오

번호 3 :

마지막 단계는 이러한 수정 사항을 저장하는 것입니다 (물론!)

여기에 이미지 설명을 입력하십시오

추신 : 다른 테이블에서 참조 된 기본 키를 수정하고 싶기 때문에 많은 작업에서 나를 구했습니다.


완벽하고 정확하게 내가 필요한 것!
Wildview

1

외래 키를 삭제하지 않고 변경하려면 다음을 수행하십시오.

ALTER TABLE child_table_name  WITH CHECK ADD FOREIGN KEY(child_column_name)
REFERENCES parent_table_name (parent_column_name) ON DELETE CASCADE

0
ALTER TABLE `tbl_celebrity_rows` ADD CONSTRAINT `tbl_celebrity_rows_ibfk_1` FOREIGN KEY (`celebrity_id`) 
REFERENCES `tbl_celebrities`(`id`) ON DELETE CASCADE ON UPDATE RESTRICT;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.