Partage
  • Partager sur Facebook
  • Partager sur Twitter

Requete DELETE sur 4 tables

    28 mars 2011 à 22:39:20

    Bonsoir,

    Je souhaiterai créer une requête SQL pour supprimer un questionnaire et tous ses fils (instructions, questions, answers). Une image est plus explicite :)

    Image utilisateur

    J'ai essayer de procéder de la sorte mais ce fut un FAIL :

    DELETE FROM  (SELECT * FROM `questionnaires` q
    
    INNER JOIN instructions i ON q.id = i.id_questionnaire
    
    INNER JOIN questions qi ON i.id = qi.id_instruction
    
    INNER JOIN answers a ON qi.id = a.id_question 
    
    WHERE id_questionnaire = 1)
    



    Je suis ouvert aux remarques :) (si vous pouviez expliquer votre façon de procéder dans la construction de vos requêtes, ça fera office de mini-cours SQL ^^)

    Cordialement Sidguia
    • Partager sur Facebook
    • Partager sur Twitter
      28 mars 2011 à 23:45:14

      En fait, ce serait plutôt à toi de nous donner plus d'infos. Ça veut dire quoi exactement, "ce fut un FAIL" ? Qu'est-ce qui se passe ? Qu'est-ce que tu veux faire ?

      A priori, tu dois simplement ajouter la contrainte ON DELETE CASCADE à tes clés étrangères.
      • Partager sur Facebook
      • Partager sur Twitter
        29 mars 2011 à 1:03:54

        Bonsoir, quand je dis ce fut un FAIL <=> ce fut un échec.

        J'ai oublier de fournir l'erreur :
        #1064 - 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 '(SELECT * FROM `questionnaires` q INNER JOIN instructions i ON q.id = i.id_qu' at line 1

        Je voudrais supprimer un questionnaire, c a d les instructions associés, les questions associées aux instructions et les réponses associées aux questions
        • Partager sur Facebook
        • Partager sur Twitter
          29 mars 2011 à 1:06:32

          La requête est syntaxiquement incorrecte. Tu ne peux pas supprimer des lignes dans une sous-requête, ça n'a pas vraiment de sens. Après, si tu veux, tu peux utiliser une sous-requête pour trier les lignes à supprimer, mais dans ton cas, ce n'est pas nécessaire.

          Comme tu n'as toujours pas expliqué ce que tu essayais de faire, je te suggère de chercher "ON DELETE CASCADE" sur Google, tu devrais trouver quelque chose.
          • Partager sur Facebook
          • Partager sur Twitter
            29 mars 2011 à 1:19:30

            Je vais regarder ça :)

            Citation : sidguia

            Je voudrais supprimer un questionnaire, c a d les instructions associés, les questions associées aux instructions et les réponses associées aux questions



            Je n'ai rien d'autre à ajouter ! ^^


            EDIT :

            J'ai fais mes recherches sur google... je n'ai pas bien compris comment utiliser "ON DELETE CASCADE". De plus Il semblerait que je dois modifier la structure de ma base pour ajouter des contraintes d'intégrité.

            Pouvez vous m'aider à formuler la requête ? Je ne suis pas beaucoup calé en SQL et le temps me manque pour me plonger dedans.

            Cordialement
            • Partager sur Facebook
            • Partager sur Twitter
              30 mars 2011 à 9:31:38

              Lis le tuto sur les relations en SQL.
              • Partager sur Facebook
              • Partager sur Twitter
                30 mars 2011 à 12:05:24

                Une piste (pour aller franchement contre les propositions de Fayden):

                CREATE TABLE t1 (v INT);
                INSERT t1 VALUES (1),(2),(3);
                -- contenu de t1: 1,2,3
                
                CREATE TABLE t2 (v INT);
                INSERT t2 VALUES (3),(4),(5);
                -- contenu de t2: 3,4,5
                
                DELETE 	t1, t2
                FROM	t1 INNER JOIN t2 ON t1.v = t2.v;
                
                SELECT * FROM t1;
                -- contenu de t1: 1,2
                SELECT * FROM t2;
                -- contenu de t2: 4,5
                


                cf: http://dev.mysql.com/doc/refman/5.0/fr/delete.html
                Syntaxe multitable:
                DELETE [LOW_PRIORITY] [QUICK] [IGNORE] table_name[.*] [, table_name[.*] ...]
                       FROM table-references
                       [WHERE where_definition]

                Tracker.
                • Partager sur Facebook
                • Partager sur Twitter
                  30 mars 2011 à 16:00:06

                  Citation : Tracker

                  Une piste (pour aller franchement contre les propositions de Fayden)


                  Ma seule proposition aura été de jeter un oeil sur le fameux ON DELETE CASCADE, et avec les informations que nous avons, je continue à croire que c'est la meilleure solution. Mais comme l'auteur ne veut absolument pas donner plus d'informations, à lui de se démerder.

                  J'aimerais bien connaître les raisons qui te poussent à aller "franchement" contre une proposition qui simplifierait énormément les requêtes.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    30 mars 2011 à 16:27:46

                    Parce que c'est de la responsabilité stricte du code (plus précisément des règles de gestion) de gérer les données pas de la base.

                    Tracker.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 mars 2011 à 16:33:41

                      Qu'entends-tu par "règle de gestion" ? À mon sens, ON DELETE CASCADE en est une.
                      Lorsqu'on supprime une ligne parente et qu'on veut aussi supprimer les lignes enfants, pourquoi se prendre solidement la tête à faire des jointures soi-même quand la norme SQL prévoit une façon simple de le faire automatiquement ?

                      Sinon, n'hésite pas à t'étendre un peu plus sur le sujet, parce que si on y va d'une phrase à la fois, on est pas sortis.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        30 mars 2011 à 16:39:28

                        Citation : Fayden

                        Lorsqu'on supprime une ligne parente et qu'on veut aussi supprimer les lignes enfants


                        ou pas, selon le cas, suivant l'utilisateur, ses droits etc...
                        c'est le principe même d'une règle de gestion.

                        Tracker.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          30 mars 2011 à 16:47:09

                          Tu sembles ne pas bien avoir lu la ligne que tu cites. Je n'ai pas énoncé une règle générale et c'est certain que si on ne veut pas virer les enfants, on n'ira pas mettre un "ON DELETE CASCADE" (duh).

                          Mais prenons le cas de l'OP : Il a une questionnaire, chaque questionnaire a des instructions, des questions et des réponses propres à lui. La seule info qu'il nous a donnée, c'est que quand il veut virer un questionnaire, il veut aussi virer les instructions, les questions et les réponses. En effet, quel est l'intérêt de garder ces trucs si le questionnaire qui s'y rattache n'existe plus ? Il existe certainement des cas où on doit faire du cas par cas (genre lorsqu'on supprime un compte d'un forum, on ne veut pas nécessairement virer ses posts), mais dans ce cas précis, avec la super description du problème de l'auteur, je ne vois pas en quoi ma proposition est fausse.

                          C'est dommage, ça aurait pu faire une discussion intéressante, mais tu n'es visiblement pas enclin à y participer.
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Anonyme
                            30 mars 2011 à 17:30:22

                            +1 Fayden

                            Citation : Tracker

                            Parce que c'est de la responsabilité stricte du code (plus précisément des règles de gestion) de gérer les données pas de la base.



                            Les règles de gestions qui concernent directement des données, et leurs qualité, intégrité, s'implémente du côté de la BDD, et pas dans le code.

                            La base de données c'est une base de faits, de propositions vraies au sens de la logique des prédicats.
                            Elles durent dans le temps, c'est le cœur du SI.

                            Le code, les applications, vont et viennent, changent aux grés des modes technologique ou de l'envie des utilisateurs tous les 6 mois.. je n'y placerai pas de règle de gestion.

                            Voir la notion de bases de données épaisses de Frédéric Brouard.

                            Là il est clair que ON DELETE CASCADE a sa place.
                            Une réponse, une question n'a pas de sens, pas de raison d'exister sans questionnaire.
                            Cela aurait pû être représenter explicitement en utilisant l'identification relative (4e exemple).
                            • Partager sur Facebook
                            • Partager sur Twitter
                              30 mars 2011 à 18:31:31

                              Ce qui peut avoir du sens c'est d'interdire dans certains cas la suppression du questionnaire s'il existe une question, ce qui est absolument interdit par la suppression en cascade, d'oú mon intervention à propos des règles de gestion. Le serveur est tenu de garantir l'intégrité ok, mais pas en supprimant des infos corrélées.
                              Bref pas la peine de tourner en rond, sidguia a maintenant le choix.

                              Tracker.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                31 mars 2011 à 9:47:15

                                Citation : Tracker

                                Ce qui peut avoir du sens c'est d'interdire dans certains cas la suppression du questionnaire s'il existe une question



                                Dans ce cas on met ON DELETE RESTRICT.

                                Implémenter l'intégrité référentielle dans l'appli, c'est généralement l'échec.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  31 mars 2011 à 10:50:49

                                  Citation : Lord Casque Noir

                                  Citation : Tracker

                                  Ce qui peut avoir du sens c'est d'interdire dans certains cas la suppression du questionnaire s'il existe une question



                                  Dans ce cas on met ON DELETE RESTRICT.

                                  Implémenter l'intégrité référentielle dans l'appli, c'est généralement l'échec.



                                  C'est la 4ème dimension ce post, alors
                                  http://dev.mysql.com/doc/refman/5.5/en [...] straints.html

                                  Citation

                                  RESTRICT: Rejects the delete or update operation for the parent table. Specifying RESTRICT (or NO ACTION) is the same as omitting the ON DELETE or ON UPDATE clause.


                                  CQFD ...

                                  Et qui a parlé de gérer l'intégrité dans le code ??? je dis juste que c'est pas le rôle de la base de supprimer automatiquement les enregistrements en suivant les FK (bien que ce soit possible) parce que souvent des règles de gestion (sur la suppression des éléments corrélés) font intervenir des traitements hors du champ de la bdd.

                                  Tracker.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    1 avril 2011 à 0:08:25

                                    Citation : Tracker

                                    RESTRICT: Rejects the delete or update operation for the parent table. Specifying RESTRICT (or NO ACTION) is the same as omitting the ON DELETE or ON UPDATE clause.



                                    Oui, c'est ce que j'ai dit plus haut : il y a un malentendu ? La valeur par défaut du ON DELETE est RESTRICT et pas CASCADE ce qui est somme toute logique.

                                    Citation : Tracker

                                    Et qui a parlé de gérer l'intégrité dans le code ??? je dis juste que c'est pas le rôle de la base de supprimer automatiquement les enregistrements en suivant les FK (bien que ce soit possible) parce que souvent des règles de gestion (sur la suppression des éléments corrélés) font intervenir des traitements hors du champ de la bdd.



                                    Si c'est l'application qui gère les suppressions en cascade, la BDD garde le rôle de maintenir l'intégrité référentielle, dans ce cas on utilise ON DELETE RESTRICT, qui interceptera les éventuels bugs de l'appli.


                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Requete DELETE sur 4 tables

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown