How to change the foreign key referential action? (behavior)

后端 未结 6 534
眼角桃花
眼角桃花 2020-11-27 13:11

I have set up a table that contains a column with a foreign key, set to ON DELETE CASCADE (delete child when parent is deleted)

What would the SQL com

相关标签:
6条回答
  • 2020-11-27 13:30

    Old question but adding answer so that one can get help

    Its two step process:

    Suppose, a table1 has a foreign key with column name fk_table2_id, with constraint name fk_name and table2 is referred table with key t2 (something like below in my diagram).

       table1 [ fk_table2_id ] --> table2 [t2]
    

    First step, DROP old CONSTRAINT: (reference)

    ALTER TABLE `table1` 
    DROP FOREIGN KEY `fk_name`;  
    

    notice constraint is deleted, column is not deleted

    Second step, ADD new CONSTRAINT:

    ALTER TABLE `table1`  
    ADD CONSTRAINT `fk_name` 
        FOREIGN KEY (`fk_table2_id`) REFERENCES `table2` (`t2`) ON DELETE CASCADE;  
    

    adding constraint, column is already there

    Example:

    I have a UserDetails table refers to Users table:

    mysql> SHOW CREATE TABLE UserDetails;
    :
    :
     `User_id` int(11) DEFAULT NULL,
      PRIMARY KEY (`Detail_id`),
      KEY `FK_User_id` (`User_id`),
      CONSTRAINT `FK_User_id` FOREIGN KEY (`User_id`) REFERENCES `Users` (`User_id`)
    :
    :
    

    First step:

    mysql> ALTER TABLE `UserDetails` DROP FOREIGN KEY `FK_User_id`;
    Query OK, 1 row affected (0.07 sec)  
    

    Second step:

    mysql> ALTER TABLE `UserDetails` ADD CONSTRAINT `FK_User_id` 
        -> FOREIGN KEY (`User_id`) REFERENCES `Users` (`User_id`) ON DELETE CASCADE;
    Query OK, 1 row affected (0.02 sec)  
    

    result:

    mysql> SHOW CREATE TABLE UserDetails;
    :
    :
    `User_id` int(11) DEFAULT NULL,
      PRIMARY KEY (`Detail_id`),
      KEY `FK_User_id` (`User_id`),
      CONSTRAINT `FK_User_id` FOREIGN KEY (`User_id`) REFERENCES 
                                           `Users` (`User_id`) ON DELETE CASCADE
    :
    
    0 讨论(0)
  • 2020-11-27 13:33

    You can simply use one query to rule them all: ALTER TABLE products DROP FOREIGN KEY oldConstraintName, ADD FOREIGN KEY (product_id, category_id) REFERENCES externalTableName (foreign_key_name, another_one_makes_composite_key) ON DELETE CASCADE ON UPDATE CASCADE

    0 讨论(0)
  • 2020-11-27 13:36

    You can do this in one query if you're willing to change its name:

    ALTER TABLE table_name
      DROP FOREIGN KEY `fk_name`,
      ADD CONSTRAINT `fk_name2` FOREIGN KEY (`remote_id`)
        REFERENCES `other_table` (`id`)
        ON DELETE CASCADE;
    

    This is useful to minimize downtime if you have a large table.

    0 讨论(0)
  • 2020-11-27 13:37
    ALTER TABLE DROP FOREIGN KEY fk_name;
    ALTER TABLE ADD FOREIGN KEY fk_name(fk_cols)
                REFERENCES tbl_name(pk_names) ON DELETE RESTRICT;
    
    0 讨论(0)
  • 2020-11-27 13:39

    Remember that MySQL keeps a simple index on a column after deleting foreign key. So, if you need to change 'references' column you should do it in 3 steps

    • drop original FK
    • drop an index (names as previous fk, using drop index clause)
    • create new FK
    0 讨论(0)
  • 2020-11-27 13:43

    I had a bunch of FKs to alter, so I wrote something to make the statements for me. Figured I'd share:

    SELECT
    
    CONCAT('ALTER TABLE `' ,rc.TABLE_NAME,
        '` DROP FOREIGN KEY `' ,rc.CONSTRAINT_NAME,'`;')
    , CONCAT('ALTER TABLE `' ,rc.TABLE_NAME,
        '` ADD CONSTRAINT `' ,rc.CONSTRAINT_NAME ,'` FOREIGN KEY (`',kcu.COLUMN_NAME,
        '`) REFERENCES `',kcu.REFERENCED_TABLE_NAME,'` (`',kcu.REFERENCED_COLUMN_NAME,'`) ON DELETE CASCADE;')
    
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
    LEFT OUTER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
        ON kcu.TABLE_SCHEMA = rc.CONSTRAINT_SCHEMA
        AND kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
    WHERE DELETE_RULE = 'NO ACTION'
    AND rc.CONSTRAINT_SCHEMA = 'foo'
    
    0 讨论(0)
提交回复
热议问题