Як додати "ON DELETE CASCADE" в операторі ALTER TABLE


130

У мене в таблиці є обмеження на зовнішній ключ, я хочу додати до нього ВИКОРИСТИТИ КАСКАД.

Я спробував це:

змінити таблицю_мення_тита_типу
  змінити обмеження fk_name
  зовнішній ключ (ім'я_кольори__колунки)
  посилання parent_table_name (parent_column_name) на каскад видалення;

Не працює.

РЕДАКТУВАННЯ:
Іноземний ключ вже існує, у стовпці з іноземними ключами є дані.

Повідомлення про помилку, яке я отримую після виконання оператора:

ORA-02275: таке референтне обмеження вже існує в таблиці

В чому проблема? Заява відхилена, видалення не відбувається ..
Thorsten

Відповіді:



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
Він дає нам увесь код. Це, очевидно, перевага для людей, які не мають нічого спільного з постгресами
Маттіс Колі

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;

Як ви бачите, ці команди повинні бути відокремлені, спочатку відкидаючи, а потім додаючи.


Це недійсне для Oracle
a_horse_with_no_name

Щойно перевірений у SqlServer, але можливо, вам доведеться скористатися goнапів-двокрапкою, як у postgres і в самому SqlServer. Але основні коди, що залишаються, - це стандарти sql. Тест з напівколонами, я просто змінив його
Девід Сільва-Баррера

У стандартних SQL (і Oracle) [або ]недійсні. Oracle також не підтримує on updateзастереження про зовнішній ключ.
a_horse_with_no_name

Ви маєте рацію, [ ]конкретні SqlServer. Я його більше очищу. Про це on updateя нічого не можу сказати.
Давид Сільва-Баррера

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 . Я відредагував код для вас, щоб зробити його більш читабельним.
Адріан Ш

3

Для всіх, хто використовує MySQL:

Якщо ви перейдете на свою PHPMYADMINвеб-сторінку і перейдете до таблиці, в якій є зовнішній ключ, який ви хочете оновити, все, що вам потрібно зробити, це натиснути на Relational view розташованій у Structureвкладці та змінити параметр On deleteвибору меню на Cascade.

Зображення показано нижче:

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


ОП працює з 2009 року, його питання Oracle позначено тегами, а PHPMYADMIN є стороннім програмним компонентом для MySQL.
vegatripy

7
Абсолютно вірно. Але я гугле за цим питанням, бажаючи знати, як це зробити в MySQL, і Google привів мене сюди. Так, питання позначено Oracle, тому ця відповідь не є правильною ... але вона буде корисна читачам, як я, які натрапляють на цю відповідь. Так само додати значення цієї сторінки, навіть якщо вона не є Oracle специфічні. Отже, дякую Джеймс111!
Майк Гледхілл

3

Ось зручне рішення! Я використовую SQL Server 2008 R2.

Оскільки ви хочете змінити обмеження FK, додавши ON DELETE / UPDATE CASCADE, виконайте наступні дії:

НОМЕР 1:

Клацніть правою кнопкою миші на обмеження та натисніть Змінити

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

НОМЕР 2:

Виберіть обмеження з лівого боку (якщо таких більше). Потім праворуч розгорніть точку " ВСТАВКА І ОНОВЛЕННЯ Специфікація " і вкажіть дії на рядок "Видалити правило" або "Оновити правило" відповідно до ваших потреб. Після цього закрийте діалогове вікно.

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

НОМЕР 3:

Останній крок - збереження модифікацій тез (звичайно!)

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

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


Ідеально, саме те, що мені було потрібно!
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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.