如何在ALTER TABLE语句中添加“ON DELETE CASCADE”

时间:2009-10-15 10:44:59

标签: sql oracle

我的表中有一个外键约束,我想在其中添加ON DELETE CASCADE。

我试过这个:

alter table child_table_name
  modify constraint fk_name
  foreign key (child_column_name)
  references parent_table_name (parent_column_name) on delete cascade;

不起作用。

编辑:
外键已经存在,外键列中有数据。

执行语句后得到的错误消息:

ORA-02275: such a referential constraint already exists in the table

8 个答案:

答案 0 :(得分:125)

您无法将ON DELETE CASCADE添加到已存在的约束中。您必须drop并重新create约束。 documentation表示MODIFY CONSTRAINT子句只能修改state of a constraint(i-e:ENABLED/DISABLED ...)。

答案 1 :(得分:59)

首先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;

答案 2 :(得分:7)

此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;

答案 3 :(得分:6)

如前所述:

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;

正如你所看到的那些必须是分开的命令,先丢弃然后添加。

答案 4 :(得分:2)

这是一个方便的解决方案! 我正在使用SQL Server 2008 R2。

如果要通过添加ON DELETE / UPDATE CASCADE来修改FK约束,请按照下列步骤操作:

NUMBER 1:

右键点击约束,然后点击 修改

enter image description here

NUMBER 2:

在左侧选择约束(如果有多个约束)。然后在右侧,折叠“ INSERT AND UPDATE Specification ”指向并指定删除规则或更新规则行上的操作以满足您的需要。之后,关闭对话框。

enter image description here

NUMBER 3:

最后一步是保存这些修改(当然!)

enter image description here

PS:因为我想要修改另一个表中引用的主键,所以它从一堆工作中救了我。

答案 5 :(得分:1)

如果您想在不删除外键的情况下更改外键,可以执行以下操作:

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

答案 6 :(得分:1)

MYSQL用户的答案:

C-u - 5 3 9

答案 7 :(得分: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;