DELETE récursif [MySQL] - SQL/NoSQL - Programmation
Marsh Posté le 22-03-2005 à 17:41:56
ReplyMarsh Posté le 23-03-2005 à 10:05:08
le pire pour toi c'est que tu as N niveau, donc tu sais pas a l'avance combien de fois tu va boucler
Marsh Posté le 23-03-2005 à 10:22:38
fabien a écrit : le pire pour toi c'est que tu as N niveau, donc tu sais pas a l'avance combien de fois tu va boucler |
bah une fonction récursive dans le langage qui tourne derrière (au pif, php... ) te fait ça sans aucun pb...
Marsh Posté le 23-03-2005 à 10:25:43
skeye a écrit : bah une fonction récursive dans le langage qui tourne derrière (au pif, php... ) te fait ça sans aucun pb... |
le probleme c'est pas le langage, mais les capacité du developpeur
Marsh Posté le 23-03-2005 à 10:52:38
ouais évidement... c'est la roue de secours, mais je prefère éviter de lancer 50 fois la meme requete avec un id qui change ...
mais bon si mysql n'a pas on sera bien obligé de coder ca
Marsh Posté le 23-03-2005 à 11:17:40
ce que tu peut faire, c'est avec un select, tu prend tous les id des sous-cat, ensuite tu fait un seul delete where id in(1,2,34,8,6,7,9)
ou un truc du genre.
Marsh Posté le 23-03-2005 à 18:28:56
Je ne sais pas si c'est possible en MySQL, mais il existe l'option 'ON DELETE CASCADE'
suffit de la présicer à la création, et toute supression supprimera en cascade dans la BD...
Marsh Posté le 23-03-2005 à 18:36:05
moi23372 a écrit : Je ne sais pas si c'est possible en MySQL, mais il existe l'option 'ON DELETE CASCADE' |
ca existe pas sur mysql je crois.
Marsh Posté le 23-03-2005 à 21:03:56
Si ta version de MySQL supporte les procédures stockées (donc une version très récente), alors tu dois pouvoir le faire en PS. Sur SQL Server en tout cas, ça marche très bien.
A noter toutefois que dans SQL Server, la limite à la récursivité est de 30 niveaux, donc même si MySQL le supporte, il aura certainement une limite aussi.
Marsh Posté le 24-03-2005 à 17:34:38
moi23372 a écrit : Je ne sais pas si c'est possible en MySQL, mais il existe l'option 'ON DELETE CASCADE' |
Cette methode permet de supprimer dans les tables liées les enregistrements faisant reference aux enregistrements supprimés.
Le probleme enoncé n'a pas de solution en requete SQL brute. La recursivité n'est pas encore native aux SGBDR. Il me semble qu'il existe qq chose sous Oracle, mais il s'agit d'une extension.
Le plus simple est de faire du recursif PHP, ou procedure stockée.
Marsh Posté le 29-03-2005 à 13:44:15
Avec Oracle, il est possible de déclarer un "trigger" qui se déclenchera à la suppression d'un enregistrement. Ainsi il est possible de supprimer les enregistrements fils dans le trigger.
Marsh Posté le 29-03-2005 à 14:15:43
Vinx a écrit : Avec Oracle, il est possible de déclarer un "trigger" qui se déclenchera à la suppression d'un enregistrement. Ainsi il est possible de supprimer les enregistrements fils dans le trigger. |
En effet. Avec SQL Server aussi d'ailleurs.
Seulement, il y a deux limites :
1) Le trigger s'appelant lui-même (puisqu'il supprimer une ligne dans la table, qui relance alors le trigger), et par défaut, que ce soit Oracle ou SQL Server, c'est désactivé : en effet, on peut rapidement planter toute la base avec un trigger de ce type mal écrit, genre un trigger sur UPDATE qui fait un update...
2) Comme pour la procédure stockée, il y a une limite à la récursivité. Sous SQL Server, c'est 30 niveaux. Avec Oracle, je ne sais à combien c'est bloqué, mais elle éxiste très certainement, notamment pour limiter les dégats dans le cas d'une erreur (1)
Marsh Posté le 29-03-2005 à 14:42:02
Vinx a écrit : Avec Oracle, il est possible de déclarer un "trigger" qui se déclenchera à la suppression d'un enregistrement. Ainsi il est possible de supprimer les enregistrements fils dans le trigger. |
Le probleme est que ca reste du recursif, et que la profondeur est limitée.
Marsh Posté le 29-03-2005 à 19:29:21
Petite précision : MySQL supporte les clefs étrangères + ON DELETE CASCADE mais uniquement sur les tables de type InnoDB.
Marsh Posté le 29-03-2005 à 19:50:17
kalex a écrit : Petite précision : MySQL supporte les clefs étrangères + ON DELETE CASCADE mais uniquement sur les tables de type InnoDB. |
Y compris sur une table qui boucle sur elle-même ? (je demande, parceque beaucoup de SGBD supportent ça de façon assez aléatoire, à cause du facteur récursif)
Marsh Posté le 29-03-2005 à 20:03:23
Arjuna a écrit : Y compris sur une table qui boucle sur elle-même ? (je demande, parceque beaucoup de SGBD supportent ça de façon assez aléatoire, à cause du facteur récursif) |
Sur ma version (4.0.24-debug) ça marche, mais je crois me souvenir qu'il y a quelque temps ce n'etait pas le cas.
Marsh Posté le 29-03-2005 à 21:25:51
cinocks a écrit : Le probleme est que ca reste du recursif, et que la profondeur est limitée. |
Oui effectivement.
J'utilise ça sur des tables différentes moi :
Par exemple :
Table VILLES : Id_ville, nom ...
Table RUES : Id_rue, nom, Id_ville ...
A l'effacement d'une ville, on peut faire: "DELETE FROM RUES WHERE RUES.Id_ville = Villes.Id_ville_supprimé"
(Désolé, je n'ai plus la syntaxe en tête. Doit y avoir un ": old" )
Marsh Posté le 29-03-2005 à 21:32:26
old.id_ville au lieu de "villes.id_ville_supprimée"
cela dit, utiliser le trigger implicite d'une FK est ce qu'il y a de mieu
Marsh Posté le 31-03-2005 à 11:07:56
Citation : A deviation from SQL standards: If ON UPDATE CASCADE or ON UPDATE SET NULL recurses to update the same table it has previously updated during the cascade, it acts like RESTRICT. This means that you cannot use self-referential ON UPDATE CASCADE or ON UPDATE SET NULL operations. This is to prevent infinite loops resulting from cascaded updates. A self-referential ON DELETE SET NULL, on the other hand, is possible from 4.0.13. A self-referential ON DELETE CASCADE has been possible since ON DELETE was implemented. Since 4.0.21, cascading operations may not be nested more than 15 levels. |
Source : http://dev.mysql.com/doc/mysql/en/ [...] aints.html
Ca devrait aller 15 niveaux pour des catégories
Marsh Posté le 31-03-2005 à 11:29:10
En effet, mais interdit de faire une telle clé sur une seule table.
Marsh Posté le 31-03-2005 à 12:00:37
ReplyMarsh Posté le 24-04-2005 à 18:33:13
_Dim_ a écrit : Bonjour, |
salut, c'est cool c'est un truc que je viens juste de faire, ça t'intéresse toujours?
moi c'est :
table categorie avec id de la catégorie et id de la catégorie mère (qui vaut zéro si on est à une catégorie principale)
j'ai un script qui fait la suppression (en php sur une base mysql) et je l'ai aussi adapté pour une modification de la valeur d'un champ.
Marsh Posté le 25-04-2005 à 09:23:49
Mouais, m'enfin c'est quand même mieu quand c'est un trigger/contrainte qui s'en charge :
-> Transactionnel (si ça plante au milieu -bug, plantage du serveur, coupure de courant, etc. -, les lignes sont remimses en l'état)
-> Impossible d'oublier de l'éxécuter, même en manuel
-> Plus rapide qu'un script externe
-> Plus joli
-> Plus mieu quoi
Marsh Posté le 22-03-2005 à 16:59:51
Bonjour,
J'aimerais savoir s'il est possible d'effecter un DELETE de manière recursif.
Je m'explique, j'ai une table "catégorie" qui contient plusieurs catégories, chaque catégorie peut être un parent/enfant d'une autre catégorie (en gros jai le champ "parent" dans la table, si c'est 0 c'est une catégorie général, et si c'est pas 0 et donc un id d'une autre catégorie, il s'agit d'une sous catégorie)
Il peut y avoir autant de sous catégorie a chaque sous catégorie qu'on veut (donc N niveaux)
Maintenant, si je viens a supprimer une catégorie, j'aimerais que ca supprime tout ces enfants ainsi que les enfants des enfants, ect ...
Est ce possible? si oui comment?
Merci d'avance
Dim
Message édité par _Dim_ le 22-03-2005 à 17:07:30