[MySQL] DELETE récursif

DELETE récursif [MySQL] - SQL/NoSQL - Programmation

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
Reply

Marsh Posté le 22-03-2005 à 16:59:51   

Reply

Marsh Posté le 22-03-2005 à 17:41:56    

non, faut que tu supprime sous-cat par sous-cat [:spamafote]


---------------
Découvre le HFRcoin ✈ - smilies
Reply

Marsh Posté le 22-03-2005 à 18:42:43    

arf quel galère, merci quand meme :(

Reply

Marsh 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 :/


---------------
Découvre le HFRcoin ✈ - smilies
Reply

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... :whistle:) te fait ça sans aucun pb...[:skeye]


Message édité par skeye le 23-03-2005 à 10:22:48

---------------
Can't buy what I want because it's free -
Reply

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... :whistle:) te fait ça sans aucun pb...[:skeye]


le probleme c'est pas le langage, mais les capacité du developpeur  [:smapafote]  
 


---------------
Découvre le HFRcoin ✈ - smilies
Reply

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 :p

Reply

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.


---------------
Découvre le HFRcoin ✈ - smilies
Reply

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...

Reply

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'
suffit de la présicer à la création, et toute supression supprimera en cascade dans la BD...


ca existe pas sur mysql je crois.


---------------
Découvre le HFRcoin ✈ - smilies
Reply

Marsh Posté le 23-03-2005 à 18:36:05   

Reply

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.

Reply

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'
suffit de la présicer à la création, et toute supression supprimera en cascade dans la BD...


 
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.


---------------
MZP est de retour
Reply

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.


---------------
Slack powa | http://www.racingpneu.com
Reply

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)

Reply

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.


---------------
MZP est de retour
Reply

Marsh Posté le 29-03-2005 à 16:21:43    

D'un autre côté, 30 niveaux, ça va, y'a de la marge...

Reply

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.

Reply

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)


Message édité par Arjuna le 29-03-2005 à 19:50:49
Reply

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.

Reply

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"  :p )


Message édité par Vinx le 29-03-2005 à 21:26:18

---------------
Slack powa | http://www.racingpneu.com
Reply

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 :)

Reply

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 ;)

Reply

Marsh Posté le 31-03-2005 à 11:29:10    

En effet, mais interdit de faire une telle clé sur une seule table.

Reply

Marsh Posté le 31-03-2005 à 12:00:37    

Arjuna a écrit :

En effet, mais interdit de faire une telle clé sur une seule table.


 :??:

Reply

Marsh Posté le 31-03-2005 à 12:27:45    

Arf, non, j'avais mal lu la seconde moitié du truc :D

Reply

Marsh Posté le 31-03-2005 à 12:29:53    

oki c'est bien ce qu'il me semblait :D

Reply

Marsh Posté le 24-04-2005 à 18:33:13    

_Dim_ a écrit :

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


 
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.

Reply

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 :p


Message édité par Arjuna le 25-04-2005 à 09:26:14
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed