J'ai une base de données Postgresql sur laquelle je veux faire quelques suppressions en cascade. Cependant, les tables ne sont pas configurées avec la règle ON DELETE CASCADE. Existe-t-il un moyen de supprimer un fichier et de demander à Postgresql de le mettre en cascade une seule fois? Quelque chose d'équivalent à
DELETE FROM some_table CASCADE;
Les réponses à cette question plus ancienne donnent l'impression qu'aucune telle solution n'existe, mais j'ai pensé que je poserais cette question explicitement juste pour être sûr.
postgresql
Eli Courtwright
la source
la source
Réponses:
Non. Pour le faire une seule fois, il vous suffit d'écrire l'instruction delete pour la table que vous souhaitez mettre en cascade.
la source
Si vous voulez vraiment
DELETE FROM some_table CASCADE;
ce qui signifie " supprimer toutes les lignes du tableausome_table
", vous pouvez utiliser à laTRUNCATE
place deDELETE
etCASCADE
est toujours pris en charge. Cependant, si vous souhaitez utiliser la suppression sélective avec unewhere
clause, ceTRUNCATE
n'est pas suffisant.UTILISER AVEC SOIN - Cela supprimera toutes les lignes de toutes les tables qui ont une contrainte de clé étrangère
some_table
et toutes les tables qui ont des contraintes sur ces tables, etc.Postgres prend
CASCADE
en charge avec la commande TRUNCATE :Il s'agit d'un processus transactionnel (c'est-à-dire qu'il peut être annulé), bien qu'il ne soit pas complètement isolé des autres transactions simultanées et comporte plusieurs autres mises en garde. Lisez les documents pour plus de détails.
la source
J'ai écrit une fonction (récursive) pour supprimer n'importe quelle ligne en fonction de sa clé primaire. J'ai écrit ceci parce que je ne voulais pas créer mes contraintes comme "sur la cascade de suppression". Je voulais pouvoir supprimer des ensembles de données complexes (en tant que DBA) mais ne pas permettre à mes programmeurs de pouvoir supprimer en cascade sans réfléchir à toutes les répercussions. Je teste toujours cette fonction, donc il peut y avoir des bogues - mais s'il vous plaît ne l'essayez pas si votre base de données a des clés primaires (et donc étrangères) multi-colonnes. De plus, les clés doivent toutes pouvoir être représentées sous forme de chaîne, mais elles peuvent être écrites d'une manière qui n'a pas cette restriction. J'utilise cette fonction TRÈS PEU de toute façon, j'apprécie trop mes données pour permettre les contraintes en cascade sur tout. Fondamentalement, cette fonction est passée dans le schéma, le nom de la table et la valeur principale (sous forme de chaîne), et il commencera par trouver toutes les clés étrangères sur cette table et s'assurera que les données n'existent pas - si c'est le cas, il s'appellera récursivement sur les données trouvées. Il utilise un tableau de données déjà marquées pour suppression pour éviter les boucles infinies. Veuillez le tester et faites-moi savoir comment cela fonctionne pour vous. Remarque: c'est un peu lent. Je l'appelle comme ça:
select delete_cascade('public','my_table','1');
la source
IN
opérateur avec des sous-sélections au lieu de=
(donc utilisez la logique des ensembles), cela deviendrait beaucoup plus rapide.Si je comprends bien, vous devriez pouvoir faire ce que vous voulez en supprimant la contrainte de clé étrangère, en en ajoutant une nouvelle (qui se mettra en cascade), en faisant votre travail et en recréant la contrainte de clé étrangère restrictive.
Par exemple:
Bien sûr, vous devez résumer des trucs comme ça dans une procédure, pour votre santé mentale.
la source
Je ne peux pas commenter la réponse de Palehorse, j'ai donc ajouté ma propre réponse. La logique de Palehorse est correcte mais l'efficacité peut être mauvaise avec des ensembles de données volumineux.
C'est plus rapide si vous avez des index sur les colonnes et que l'ensemble de données est plus grand que quelques enregistrements.
la source
Oui, comme d'autres l'ont dit, il n'y a pas de 'DELETE FROM my_table ... CASCADE' (ou équivalent). Pour supprimer les enregistrements enfants protégés par une clé étrangère non en cascade et leurs ancêtres référencés, vos options incluent:
C'est à dessein que contourner les contraintes de clés étrangères n'est pas commode, je suppose; mais je comprends pourquoi, dans des circonstances particulières, vous voudriez le faire. Si c'est quelque chose que vous ferez avec une certaine fréquence, et si vous êtes prêt à bafouer la sagesse des DBA partout, vous voudrez peut-être l'automatiser avec une procédure.
Je suis venu ici il y a quelques mois à la recherche d'une réponse à la question "CASCADE DELETE juste une fois" (initialement posée il y a plus d'une décennie!). J'ai tiré un certain kilométrage de la solution intelligente de Joe Love (et de la variante de Thomas CG de Vilhena), mais à la fin mon cas d'utilisation avait des exigences particulières (gestion des références circulaires intra-table, par exemple) qui m'ont forcé à adopter une approche différente. Cette approche est finalement devenue récursivement supprimée (PG 10.10).
J'utilise recursively_delete en production depuis un certain temps, maintenant, et finalement je me sens (prudemment) suffisamment confiant pour le mettre à la disposition de ceux qui pourraient se retrouver ici à la recherche d'idées. Comme avec la solution de Joe Love, elle vous permet de supprimer des graphiques entiers de données comme si toutes les contraintes de clé étrangère dans votre base de données étaient momentanément définies sur CASCADE, mais offre quelques fonctionnalités supplémentaires:
la source
Vous pouvez utiliser pour automatiser cela, vous pouvez définir la contrainte de clé étrangère avec
ON DELETE CASCADE
.Je cite le manuel des contraintes de clé étrangère :
la source
J'ai pris la réponse de Joe Love et l'ai réécrite en utilisant l'
IN
opérateur avec des sous-sélections au lieu de=
rendre la fonction plus rapide (selon la suggestion de Hubbitus):la source
in
opérateur et des sous-requêtes.L'option de suppression avec cascade s'applique uniquement aux tables avec des clés étrangères définies. Si vous effectuez une suppression, et il est dit que vous ne pouvez pas, car cela violerait la contrainte de clé étrangère, la cascade entraînera la suppression des lignes incriminées.
Si vous souhaitez supprimer les lignes associées de cette manière, vous devrez d'abord définir les clés étrangères. N'oubliez pas non plus que, sauf si vous lui demandez explicitement de commencer une transaction ou si vous modifiez les valeurs par défaut, il effectuera une validation automatique, ce qui pourrait prendre beaucoup de temps à nettoyer.
la source