IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

DELETE multi-tables avec jointures


Sujet :

Requêtes MySQL

  1. #1
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut DELETE multi-tables avec jointures
    Bonjour,

    Je cherche à pouvoir supprimer un forum en une seule requête, donc à effacer également des autres tables les entrées en relation avec ce forum.

    Mais quoi que je fasse, MySQL me retourne une erreur de syntaxe du genre :
    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'RIGHT JOIN sujet AS S ON F.id=S.id_forum RIGHT JOIN forum_prive AS FP' at line 2

    C'est possible de faire un DELETE sur plusieurs tables, d'après la doc, j'ai vu que oui, mais je commence à douter.

    Une des multiples requêtes que j'ai tenté :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    DELETE LOW_PRIORITY FROM forum AS F
    RIGHT JOIN sujet AS S ON F.id=S.id_forum
    RIGHT JOIN forum_prive AS FP ON F.id=FP.id_forum
    RIGHT JOIN message AS M ON S.id=M.id_sujet
    RIGHT JOIN nb_lecture_sujet AS NLS ON S.id=NLS.id_sujet
    RIGHT JOIN sujet_lecture_membre AS SLM ON S.id=SLM.id_sujet
    WHERE F.id=5
    Ma version de MySQL est la 5.0.18, donc normalement c'est ok.

    C'est possible de faire ceci, ou je suis contraint de le faire en plusieurs requêtes ?

  2. #2
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    DELETE LOW_PRIORITY F, S, FP, M, NLS, SLM
    FROM forum AS F
    RIGHT JOIN sujet AS S ON F.id=S.id_forum
    RIGHT JOIN forum_prive AS FP ON F.id=FP.id_forum
    RIGHT JOIN message AS M ON S.id=M.id_sujet
    RIGHT JOIN nb_lecture_sujet AS NLS ON S.id=NLS.id_sujet
    RIGHT JOIN sujet_lecture_membre AS SLM ON S.id=SLM.id_sujet
    WHERE F.id=5
    devrait marcher.

  3. #3
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Je vais tenté ça, merci.

    Désolé de ma réponse tardive

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 147
    Points : 102
    Points
    102
    Par défaut
    Sinon, tu peux ajouter un "ON DELETE CASCADE" et ça va tout te supprimer comme il faut et automatiquement. Super pratique.

  5. #5
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Oui, mais à ce que j'ai vu, faut que mes tables soient en INNODB, je les ai mises en MyISAM pour le fulltext.

    Et puis, j'ai pas mis de clefs étrangères sur mes tables

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 52
    Points : 50
    Points
    50
    Par défaut trigger ?
    Et avec des trigger ?

  7. #7
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Je viens de regarder la doc MySQL sur le triggers, j'avoue ne pas avoir bien compris à quoi ça sert

  8. #8
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    En gros un trigger c'est des opérations qui sont déclanchées à chaque fois qu'une requête d'un type donné est réalisée sur une table donnée. Cela pourrait se faire via le code client mais un trigger garantie que ce sera systématique et qu'il n'y aura pas d'étourderie.

    Par exemple on peut faire en sorte qu'à chaque insertion dans une table 'client' un enregistrement correspondant soit créé dans la table 'compteclient'. Ou pour un forum qu'une insertion d'un 'post' mette à jour le compte des messages et la date du dernier message du thread correspondant. Comme ça pas besoin de faire des requêtes complexes quand on affiche la liste des threads.

    Ici un trigger sur tout delete dans 'forum' pourrait faire les deletes correspondant dans 'sujet' et compagnie.

  9. #9
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Ah mais c'est cool ça

    C'est bizarre, mais j'en ai jamais entendu parlé.

    Je vais essayer de trouver de la doc dessus pour comprendre comment ça fonctionne.

    Merci !

    Donc, si j'ai bien compris tous les updates de tables qui doivent se faire après l'insert dans une table spécifique, je peux les virer du php, et les déclarer en trigger ?

    Si c'est vraiment ça, c'est génial ce truc !!!

  10. #10
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Bon, j'ai été voir un peu comment ça fonctionnait, mais par contre, j'ai pas trouvé comment on pouvait updater une table sur une ligne précise.

    C'est vraiment possible de faire comme tu dis pour un forum par exemple.

    C'est à dire qu'à l'INSERT d'un message, je puisse via un TRIGGER mettre à jour le nombre de sujet correspondant ?

    Comment faire pour indiquer l'id du sujet à updater ?

    La doc MySQL est un peu flou

    J'ai été voir ici, j'ai trouvé http://maximilian.developpez.com/mys...tes_mysql5/#LB

    Mais pareil, j'ai pas trouvé une méthode opérant un truc équivalant.

    Je n'ai pas compris non plus les new et old :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ..... WHERE id_equipe=new.id_visiteurs;
    Ca fonctionne comment ?

    Merci.

  11. #11
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    En ce qui me concerne les triggers c'était en cours (donc ça date un brin) et sous Oracle. Mais pour ce que j'en sais :

    Il faut déjà déterminer si l'on veut agir pour chaque modification d'une table ou d'une ligne, une requête pouvant modifier de multiples lignes (d'où le 'FOR EACH ROW')... et je viens de voir que pour mysql 'FOR EACH ROW' est encore obligatoire.

    On peut aussi décider de faire ça avant ou après l'exécution de la requête.

    Ensuite 'old' et 'new' font référence à la ligne modifiée pour laquelle le trigger est exécuté (puisque l'on a 'FOR EACH ROW') dans ses états avant et après modification. Ce qui répond à :
    Citation Envoyé par Xunil
    Comment faire pour indiquer l'id du sujet à updater ?
    puisque généralement un message a comme clef étrangère l'id du sujet auquel il se rapporte ('new.id_sujet' par exemple).

    A noter que pour une insertion il n'y a pas de 'old'.

  12. #12
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Ca y est, j'ai réussi à le faire fonctionner.

    J'ai fait ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TRIGGER AI_nb_sujet 
    AFTER INSERT ON sujet
    FOR EACH ROW 
    UPDATE forum SET nb_sujet=nb_sujet+1
    WHERE forum.id=new.id_forum;
     
    CREATE TRIGGER AI_nb_message
    AFTER INSERT ON message
    FOR EACH ROW 
    UPDATE sujet SET nb_message=nb_message+1
    WHERE sujet.id=new.id_sujet;
    C'était pas compliqué en fait.

    En question de rapidité d'exécution, on est gagnant à utiliser des trigger ?

    Merci de ta patience

  13. #13
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Je n'ai aucun chiffre à donner (et pas d'expérience personnelle).

    C'est certainement mieux que lancer la requête à la main : pas d'oubli, pas besoin d'envoyer la requête au serveur et ce dernier doit pouvoir économiser son décodage.

    Après si c'est faire une mise à jour plutôt que compter... Ca dépend d'énormément de chose : rapport entre insertions et comptes, indexes, query cache, taille... Un simple count sur une table indexée pourrait bien être assez rapide.
    Ce genre de mise à jour pourrait peut-être être bien plus utile pour ce qui est difficile à faire en SQL, comme la récupération pour chaque thread de l'identifiant de l'utilisateur qui a posté le dernier message (ou autre truc du genre) qui est un classique de ces forums car il n'y a pas de façon propre de le faire en SQL pur Cela dit si on met une info autant garder le compte des messages au passage, ça ne coûte rien

  14. #14
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Ok, merci beaucoup de tes explications

    Mais en tout cas, je suis content d'avoir découvert grâce à vous les trigger, je crois que je vais plus pouvoir m'en passer

    J'ai déjà plein d'idées d'utilisations dans la tête.

    Merci à tous

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. DELETE sur tables avec jointure
    Par iDaaX dans le forum Langage SQL
    Réponses: 1
    Dernier message: 08/03/2013, 09h46
  2. delete sur une table avec jointure
    Par Jarod51 dans le forum Requêtes
    Réponses: 2
    Dernier message: 30/09/2011, 11h26
  3. erreur de syntaxe DELETE multi-tables
    Par yayacameleon dans le forum Requêtes
    Réponses: 7
    Dernier message: 12/04/2006, 12h34
  4. Réponses: 10
    Dernier message: 27/03/2006, 15h40
  5. Sélection multi table avec condition
    Par iuz dans le forum Langage SQL
    Réponses: 8
    Dernier message: 05/05/2004, 16h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo