2011-08-16 6 views
5

J'ai 4 tables. Dans la première table a appid comme clé primaire et dans les trois autres table sa clé étrangère. Je veux supprimer des données de toutes les trois dans une requête. J'ai essayé de mon mieux mais j'ai échoué. Quelqu'un peut-il aider?Supprimer des enregistrements de plusieurs tables simultanément?

+0

C'est le problème que l'action référentielle 'ON DELETE CASCADE' a été inventée pour résoudre. Contrairement à @ Tony Andrews, je le recommande comme pratique générale. – onedaywhen

Répondre

10

Vous ne pouvez pas écrire une instruction delete faisant référence à plusieurs tables, vous devez écrire 4 instructions delete. Toutefois, si nécessaire, vous pouvez définir les clés étrangères des trois tables enfants sur "ON DELETE CASCADE". Ensuite, lorsque vous supprimez de la table parent, toutes les lignes associées des 3 tables enfants sont également supprimées. Cela peut être utile parfois, mais je ne le recommanderais pas comme une pratique générale car cela peut être dangereux et déroutant pour les développeurs.

+0

Pouvez-vous développer la nature dangereuse et déroutante des clés étrangères en cascade? Parce que je suis un peu surpris par cette remarque. – Rene

+2

@Rene, OK Bien que je travaille actuellement sur un projet où quelqu'un a mis en place beaucoup de clés étrangères comme ON DELETE CASCADE. Ainsi, par exemple, si un utilisateur fait quelque chose comme 'DELETE order_status_lookup WHERE status_code = 'SHIPPED'' alors il réussit et tous les ordres avec le statut' SHIPPED 'sont également supprimés. J'appelle ça un mais dangereux! J'utilise réellement ON DELETE CASCADE, mais seulement là où cela a vraiment du sens. –

+0

Donc, ce que vous dites, c'est que c'est un outil qui peut être très utile mais qui peut être dangereux. Un peu comme une tronçonneuse n'est-ce pas? Mais recommanderiez-vous de couper tous ces arbres manuellement? – Rene

3

Il n'existe aucun moyen de supprimer de nombreuses tables avec une seule instruction, mais la meilleure question est pourquoi devez-vous supprimer de toutes les tables en même temps? Il me semble que vous ne comprenez pas complètement comment les transactions fonctionnent dans Oracle. Disons que vous vous connectez et supprimez une ligne de la table 1, mais ne commettez pas. En ce qui concerne toutes les autres sessions, cette ligne n'a pas été supprimée. Si vous ouvrez une autre connexion et interrogez la ligne, elle sera toujours présente.

Ensuite, vous supprimez à tour de rôle les tableaux 2, 3 et 4. Vous n'avez toujours pas validé la transaction, de sorte que toutes les autres sessions de la base de données peuvent toujours voir les lignes supprimées.

Ensuite, vous validez. En même temps, les autres sessions ne verront plus les lignes que vous avez supprimées des 4 tables, même si vous avez effectué les suppressions dans 4 instructions distinctes.

+4

Je pense que vous êtes un peu dur. Je peux voir le mérite dans une syntaxe 'DELETE ALL' analogue à' INSERT ALL': il serait utile de zapper tous les enregistrements liés dans un ensemble de tables sans avoir à se soucier des dépendances et sans utiliser de contraintes différées. (Bien que j'admette que mon besoin en soit de gérer des données de test plutôt que dans des environnements de production). – APC

+0

+1 Pour une réponse claire et précise. – Rene

-2

Si la base de données est Mysql, vous pouvez utiliser join dans l'instruction DELETE. Voir http://dev.mysql.com/doc/refman/5.0/en/delete.html pour plus d'informations.

+4

Mais ce n'est pas le cas. C'est Oracle. –

+0

Outre un autre commentaire (transaction ou suppression de cascade), vous pouvez utiliser le déclencheur pour la suppression des tables enfant. –

Questions connexes