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)
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
:
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.
ALTER TABLE DROP FOREIGN KEY fk_name;
ALTER TABLE ADD FOREIGN KEY fk_name(fk_cols)
REFERENCES tbl_name(pk_names) ON DELETE RESTRICT;
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
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
drop index
)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'