ChatGPT解决这个技术问题 Extra ChatGPT

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

我的表中有一个外键约束,我想在其中添加 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
有什么问题?该语句被拒绝,删除不会发生..

M
Mark Rotteveel

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


如果这个答案描述了它是如何完成的而不是指向文档,那将会很有帮助。
D
David Silva-Barrera

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

他为我们提供了整个代码,这对于与 postgres 无关的人来说显然是一个优势
@WiiMaxx 创始人是一个嫉妒的家伙。大声笑这个答案比第一个答案更重要,因为这也提供了代码..
D
David Silva-Barrera

如前所述:

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 无效
刚刚在 SqlServer 中进行了测试,但您可能不得不像在 postgres 和 SqlServer 本身中那样使用分号 go。但剩下的核心代码是sql标准。用分号测试,我刚改了
[] 在标准 SQL(和 Oracle)中无效。 Oracle 也不支持外键的 on update 子句。
没错,[ ] 是特定于 SqlServer 的。我会多清理的。关于on update,我无话可说。
A
Adrian W

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 中的格式化代码。我为您编辑了代码以使其更具可读性。
s
shindigo

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

S
Serge Kishiko

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

当您想通过添加 ON DELETE/UPDATE CASCADE 来修改 FK 约束时,请执行以下步骤:

1号:

右键单击约束并单击以修改

https://i.stack.imgur.com/gJI0j.jpg

2号:

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

https://i.stack.imgur.com/wubl8.jpg

3 号:

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

https://i.stack.imgur.com/4FNG0.jpg

PS:当我想修改另一个表中引用的主键时,它使我免于繁重的工作。


完美,正是我需要的!
不客气@Wildview。当然很高兴为您提供帮助
C
Community

对于使用 MySQL 的任何人:

如果您进入 PHPMYADMIN 网页并导航到包含要更新的外键的表,您只需点击 Structure 标签中的 Relational view 并更改 On delete 选择菜单Cascade 的选项。

如下图所示:

https://i.stack.imgur.com/TOn4p.png


OP 从 2009 年开始,其 Oracle 问题已标记,PHPMYADMIN 是 MySQL 的第三方软件组件。
千真万确。但是我用谷歌搜索了这个问题,想知道如何在 MySQL 中做到这一点,谷歌把我带到了这里。是的,这个问题是用 Oracle 标记的,所以这个答案是不正确的......但它对像我这样偶然发现这个答案的读者很有用。所以它确实为这个页面增加了价值,即使它不是特定于 Oracle 的。所以,谢谢詹姆斯111!
此外,这种方法的一个好处是 PHPMYADMIN 做了艰苦的工作。您不必先删除约束。确保表是 INNODB。
R
RedPelle

如果您想更改外键而不删除它,您可以执行以下操作:

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

不错的解决方案,但请注意,您实际上是在此处添加另一个外键
R
Ryabchenko Alexander

对于PostgreSQL

BEGIN TRANSACTION ;
ALTER TABLE bank_accounts
    DROP CONSTRAINT bank_accounts_company_id_fkey;

ALTER TABLE bank_accounts
    ADD CONSTRAINT bank_accounts_company_id_fkey FOREIGN KEY (company_id)
        REFERENCES companies (id)
        ON DELETE CASCADE;
END;

H
Hassan Ali Shahzad
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;

P
Phúc Tĩnh

MySQL workbench img 右键单击要更改的表并单击更改表,然后单击外键。您可以在右侧看到外键选项,只需选择级联并单击应用!