Question

J'ai une table MySQL auto-référentielle avec un parent_id récursif:

CREATE TABLE `recursive` (
  `id` int(11) NOT NULL auto_increment,
  `parent_id` int(11) default NULL,
  `name` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `data_categorysource_parent_id` (`parent_id`),
  CONSTRAINT `parent_id_refs_id_627b4293`
    FOREIGN KEY (`parent_id`) REFERENCES `data_categorysource` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Pendant les tests, je souhaite le vider, mais échec de TRUNCATE:

TRUNCATE `recursive` 
/* SQL Error: Cannot delete or update a parent row: a foreign key
constraint fails...

Je dois actuellement supprimer manuellement tous les enregistrements, en commençant par le bas de l'arborescence, en commençant par le haut. Cela devient difficile même avec de petits arbres.

Y at-il un moyen facile de contourner cela? Je ne peux pas DROP la table et la recréer facilement, car d'autres tables la référencent (j'ai déjà tronqué celles-ci, il ne devrait donc y avoir aucun problème d'intégrité des données).

Était-ce utile?

La solution

Pourquoi pas:

UPDATE 'recursive' SET 'parent_id' = NULL WHERE 'parent_id' IS NOT NULL;
DELETE FROM 'recursive';

?

Autres conseils

Si vous souhaitez simplement vider l'ensemble du contenu à des fins de test, utilisez:

SET FOREIGN_KEY_CHECKS = 0;

// Execute Query

SET FOREIGN_KEY_CHECKS = 1;

Ceci contourne totalement les vérifications de clé étrangère.

Eh bien, vous pouvez ajouter un ON DELETE CASCADE à la FOREIGN KEY définition ... au moins temporairement. Cela vous permettrait de tronquer la table en supprimant d’abord les lignes référencées.

Il existe d'autres ON DELETE les types aussi; la valeur par défaut est ON DELETE NO ACTION.

Ou simplement supprimer la contrainte de clé étrangère (récursive), puis tronquer la table, puis rajouter la contrainte.

Sélectionnez à plusieurs reprises les lignes qui n'apparaissent pas en tant que parents et supprimez-les jusqu'à ce que le tableau soit vide. (En supposant qu'il n'y ait pas de cycles ...)

supprimer de la table_1 où date (table_1_TIME) < (sélectionnez T.t_Date à partir de (sélectionnez max (date (table_1_TIME)) en tant que t_Date de la table_1) en tant que T)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top