Как добавить 'ON DELETE CASCADE' в инструкции ALTER TABLE

У меня есть ограничение внешнего ключа в моей таблице, я хочу добавить к нему 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;

Не работает.

EDIT:
Внешний ключ уже существует, в столбце внешнего ключа есть данные.

Сообщение об ошибке, которое я получаю после выполнения инструкции:

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

Ответ 1

Вы не можете добавить ON DELETE CASCADE к уже существующему ограничению. У вас должно быть drop и re create ограничение. документация показывает, что предложение MODIFY CONSTRAINT может изменять только состояние ограничения (т.е.: ENABLED/DISABLED...).

Ответ 2

Сначала 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;

Ответ 3

Этот PL * SQL будет записывать в DBMS_OUTPUT a script, который удаляет каждое ограничение, которое не имеет каскада удаления и воссоздает его с помощью каскада delete.

ПРИМЕЧАНИЕ. Выполнение вывода этого script - это ВАШ СОБСТВЕННЫЙ РИСК. Лучше всего читать результирующий script и редактировать его перед его выполнением.

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;

Ответ 4

Как объяснялось ранее:

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;

Как вы можете видеть, эти команды должны быть отделены друг от друга, сначала отбрасывая, затем добавляя.

Ответ 5

Для тех, кто использует MySQL:

Если вы заходите на свою веб-страницу PHPMYADMIN и переходите к таблице с внешним ключом, которую хотите обновить, все, что вам нужно сделать, это нажать кнопку Relational view, расположенную на вкладке Structure, и изменить On delete выберите пункт меню Cascade.

Изображение, показанное ниже:

введите описание изображения здесь

Ответ 6

Вот удобное решение! Я использую SQL Server 2008 R2.

Поскольку вы хотите изменить ограничение FK, добавив ON DELETE/UPDATE CASCADE, выполните следующие действия:

НОМЕР 1:

Щелкните правой кнопкой мыши по ограничению и выберите " Изменить".

enter image description here

НОМЕР 2:

Выберите свое ограничение на левой стороне (если их больше одного). Затем с правой стороны сверните точку "ВСТАВИТЬ И ОБНОВИТЬ спецификацию" и укажите действия в строке "Удалить правило" или "Обновить правило" в соответствии с вашими потребностями. После этого закройте диалоговое окно.

enter image description here

НОМЕР 3:

Последний шаг - сохранить изменения этих тезисов (конечно!)

enter image description here

PS: Это спасло меня от кучки работы, поскольку я хочу изменить первичный ключ, указанный в другой таблице.

Ответ 7

Если вы хотите изменить внешний ключ, не удаляя его, вы можете сделать:

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

Ответ 8

Ответ для пользователей 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;

Ответ 9

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;