Как добавить '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
8 ответов:
вы не можете добавить
ON DELETE CASCADE
к уже существующему ограничению. Вам придетсяdrop
и повторноcreate
ограничения. Элемент документация видно, чтоMODIFY CONSTRAINT
предложение может изменить только государственные ограничения (i-e:ENABLED/DISABLED
...).
первый
drop
ваш внешний ключ и попробуйте выполнить команду выше, putadd 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;
этот PL * SQL запишет в DBMS_OUTPUT скрипт, который отбросит каждое ограничение, которое не имеет delete cascade, и воссоздаст его с помощью delete cascade.
Примечание: запуск вывода этого скрипта осуществляется на свой страх и риск. Лучше всего прочитать полученный скрипт и отредактировать его перед выполнением.
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;
Как уже было сказано:
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;
Как вы можете видеть, эти команды должны быть разделены, сначала отбрасывая, а затем добавляя.
вот удобное решение! Я использую SQL Server 2008 R2.
Как вы хотите изменить ограничение FK, добавив на DELETE/UPDATE CASCADE, выполните следующие действия:
номер 1:
щелкните правой кнопкой мыши на ограничении и нажмите на изменить
номер 2:
выберите ограничение с левой стороны (если их несколько). Затем с правой стороны, свернуть "вставить и обновить спецификацию" укажите и укажите действия по удалению правила или обновлению строки правила в соответствии с вашими потребностями. После этого закройте диалоговое окно.
номер 3:
последний шаг-сохранить изменения тезисов (конечно!)
PS: это спасло меня от кучи работы, поскольку я хочу изменить первичный ключ, на который ссылается другой стол.