web-dev-qa-db-fra.com

Comment changer l'action référentielle de clé étrangère? (comportement)

J'ai configuré une table contenant une colonne avec une clé étrangère, définie sur ON DELETE CASCADE (enfant à supprimer lorsque le parent est supprimé) 

Quelle serait la commande SQL pour changer ceci en ON DELETE RESTRICT? (impossible de supprimer le parent s'il a des enfants)

77
Moak

Ancienne question mais ajout de réponse pour pouvoir obtenir de l'aide

Son processus en deux étapes: 

Supposons qu'un table1 ait une clé étrangère avec le nom de colonne fk_table2_id, avec contrainte nom fk_name et table2 est référencé table avec la clé t2 (comme ci-dessous dans mon diagramme ). 

   table1 [ fk_table2_id ] --> table2 [t2]

Première étape, abandonner l'ancien CONTRAINT: ( référence

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

la contrainte de notification est supprimée, la colonne n'est pas supprimée

Deuxième étape, AJOUTER un nouveau CONTRAINT: 

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

ajoutant une contrainte, la colonne est déjà là

Exemple: 

J'ai une table UserDetails fait référence à la table Users

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`)
:
:

Premier pas: 

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

Deuxième étape: 

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)  

résultat: 

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
:
139
Grijesh Chauhan

Vous pouvez le faire en une requête if si vous souhaitez modifier son nom:

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

Ceci est utile pour minimiser les temps d'arrêt si vous avez une grande table.

12
Romuald Brunet
ALTER TABLE DROP FOREIGN KEY fk_name;
ALTER TABLE ADD FOREIGN KEY fk_name(fk_cols)
            REFERENCES tbl_name(pk_names) ON DELETE RESTRICT;
10
pascal

Vous pouvez simplement utiliser une requête pour les gouverner tous: 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

3
stamster

N'oubliez pas que MySQL conserve un index simple sur une colonne après la suppression de la clé étrangère. Donc, si vous devez changer la colonne 'références', vous devez le faire en 3 étapes

  • déposer FK d'origine
  • déposer un index (nom comme fk précédent, en utilisant la clause drop index)
  • créer un nouveau FK
3
Vasiliy

J'avais un tas de FK à modifier, alors j'ai écrit quelque chose pour faire les déclarations pour moi. Je pensais partager:

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
DavidSM