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

Zend_Db PHP Discussion :

Suppression en cascade sur plusieurs niveaux [Fait] [ZF 1.5]


Sujet :

Zend_Db PHP

  1. #1
    Membre expert
    Avatar de Janitrix
    Inscrit en
    Octobre 2005
    Messages
    3 391
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 3 391
    Points : 3 401
    Points
    3 401
    Par défaut Suppression en cascade sur plusieurs niveaux
    Salut,

    J'ai plusieurs tables MySQL telles que :
    "comment" dépend de "article", "article" dépend de "rubric", "rubric" dépend de blog.

    Dans les classes modèles, les variables _dependantTables et _referenceMap sont faites pour représenter cette structure.

    Les propriétés 'onDelete' des entrées de _referenceMap sont en "CASCADE".

    Or, lorsque je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $rubric = $rubricAdapter->find( $id )->current();
                    $rubric->delete();
    Les articles sont bien supprimés, mais pas les commentaires. De même si je supprime un blog, les rubriques sont supprimées, mais ni les articles ni les commentaires. Il semble qu'un seul niveau soit traité. Existe-t-il un moyen de régler ce problème, sans rajouter un lien dans la base de données entre tous les niveaux ?


  2. #2
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Bonjour,

    Citation Envoyé par Janitrix Voir le message
    Existe-t-il un moyen de régler ce problème, sans rajouter un lien dans la base de données entre tous les niveaux ?
    surcharger la méthode delete() de Zend_Db_Table ?

    Pour moi, ce cas ressemble bien à un bug du framework (ou au moins une absence de fonctionnalité). En fait, quand tu appelles la méthode delete() de Zend_Db_Table_Row, cela déclenche la méthode _cascadeDelete des tables enfant. Cette méthode _cascadeDelete appele à son tour la méthode delete() de Zend_Db_Table. C'est ici qu'il y a à mon sens un oubli : il n'y a pas de vérification d'existence de tables dépendantes... D'ailleurs, si au lieu de passer par un Zend_Db_Table_Row pour faire ton delete, tu avais fait simplement un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $rubricAdapter->delete("mon_id = $id")
    aucune autre table que rubric n'aurait été impactée...

    Après, ce qui me semble compliqué dans la surcharge du delete() de Zend_Db_Table, c'est que pour utiliser le _cascadeDelete, il faudrait récupérer toutes les clés primaires des éléments supprimés...

    Pour conclure, si j'avais besoin de cette fonctionnalité, je pense que j'essaierai autant que possible d'utiliser les fonctionnalités offertes par le SGBD plutôt que celles du framework (contraintes avec on delete cascade, triggers...).

    Bon courage

  3. #3
    Membre expert
    Avatar de Janitrix
    Inscrit en
    Octobre 2005
    Messages
    3 391
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 3 391
    Points : 3 401
    Points
    3 401
    Par défaut
    Merci de la réponse. Je viens de regarder le code ZF et ça semble en effet complexe de surcharger cette méthode. Je vais voir.
    Merci

  4. #4
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Points : 29 985
    Points
    29 985
    Par défaut
    C'est le job du SGBD de conserver l'intégrité référentielle. Es-tu certain d'avoir bien mis les bonnes clefs, les bonnes contraintes où il faut ?

  5. #5
    Membre expert
    Avatar de Janitrix
    Inscrit en
    Octobre 2005
    Messages
    3 391
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 3 391
    Points : 3 401
    Points
    3 401
    Par défaut
    Citation Envoyé par Yogui Voir le message
    C'est le job du SGBD de conserver l'intégrité référentielle. Es-tu certain d'avoir bien mis les bonnes clefs, les bonnes contraintes où il faut ?
    J'ai une bdd MySQL donc pas d'intégrité référentielle. Je vais voir avec les tables innoDb, il parait qu'elles gèrent l'intégrité .

  6. #6
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Points : 29 985
    Points
    29 985
    Par défaut
    Oui, avoir une base MySQL n'est pas une excuse. Le moteur InnoDB gère les sous requêtes, l'intégrité référentielle et les transactions depuis bien longtemps.

    [Edit] Question de performances, obliger ZF à s'occuper de l'intégité signifie que tu envoies de très nombreuses requêtes à ta BDD, donc de nombreux allers-retours entre ton appli et ton SGBD, donc une très grosse perte de performances par rapport à l'intégrité gérée en interne par les contraintes de tes tables.

    [Edit 2] Tutoriel MySQL : Limiter la complexité du code applicatif grâce au SGBD par Alain Defrance

  7. #7
    Membre expert
    Avatar de Janitrix
    Inscrit en
    Octobre 2005
    Messages
    3 391
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 3 391
    Points : 3 401
    Points
    3 401
    Par défaut
    Merci du lien

  8. #8
    Membre éclairé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    948
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 948
    Points : 719
    Points
    719
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // On récupère les retours d'erreurs du SGBD
            if(mysql_errno() == 1048) // un champ est vide
            {
    		    $msg = explode('\'', mysql_error(), 3);
    		    switch ($msg[1])
    		    {
    		    	case 'prenomClient':
    		    		echo '[Erreur] Le prénom doit être saisie';
    		    		break;
    		    	case 'nomClient':
    		    		echo '[Erreur] Le nom doit être saisie';
    		    		break;
    		    }
            }
    vous avez deja essayé ce genre de code?

    ca fait un peu peur non?

  9. #9
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Citation Envoyé par hansaplast Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // On récupère les retours d'erreurs du SGBD
            if(mysql_errno() == 1048) // un champ est vide
            {
    		    $msg = explode('\'', mysql_error(), 3);
    		    switch ($msg[1])
    		    {
    		    	case 'prenomClient':
    		    		echo '[Erreur] Le prénom doit être saisie';
    		    		break;
    		    	case 'nomClient':
    		    		echo '[Erreur] Le nom doit être saisie';
    		    		break;
    		    }
            }
    vous avez deja essayé ce genre de code?

    ca fait un peu peur non?
    Non, je n'ai jamais essayé (et je ne vais le faire de suite ! ).
    Mais quel est le lien avec ce sujet ?

  10. #10
    Membre expert
    Avatar de Janitrix
    Inscrit en
    Octobre 2005
    Messages
    3 391
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 3 391
    Points : 3 401
    Points
    3 401
    Par défaut
    Ce code est proposé dans l'article conseillé par Yogui

  11. #11
    Membre expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Points : 3 344
    Points
    3 344
    Par défaut
    Citation Envoyé par Janitrix Voir le message
    Ce code est proposé dans l'article conseillé par Yogui
    Ah, ok, je ne comprenais pas d'où ça venait !

  12. #12
    Membre expert
    Avatar de Janitrix
    Inscrit en
    Octobre 2005
    Messages
    3 391
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 3 391
    Points : 3 401
    Points
    3 401
    Par défaut
    Citation Envoyé par hansaplast Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // On récupère les retours d'erreurs du SGBD
            if(mysql_errno() == 1048) // un champ est vide
            {
    		    $msg = explode('\'', mysql_error(), 3);
    		    switch ($msg[1])
    		    {
    		    	case 'prenomClient':
    		    		echo '[Erreur] Le prénom doit être saisie';
    		    		break;
    		    	case 'nomClient':
    		    		echo '[Erreur] Le nom doit être saisie';
    		    		break;
    		    }
            }
    vous avez deja essayé ce genre de code?

    ca fait un peu peur non?
    Qu'est ce qui te gêne dans ce code ?

  13. #13
    Membre éclairé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    948
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 948
    Points : 719
    Points
    719
    Par défaut
    Citation Envoyé par Janitrix Voir le message
    Qu'est ce qui te gêne dans ce code ?
    ce qui me gene c'est :
    1- la dépendance envers les messages d'erreurs du moteur utilisé (je n'ai aucune idée de leur stabilité)
    2- la dépendance envers le moteur de stockage a l'heure de PDO et autre.
    3- la dependance envers les noms des colonnes.

    et puis, plus globalement, le flou entre filtrage des entrées, soumission de la requête, et retours d'erreur de saisie.

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

Discussions similaires

  1. [SQL] Affichage sur plusieurs niveaux
    Par oim dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 10/12/2007, 14h52
  2. [Débutant] Suppression de valeur sur plusieur table
    Par neuneu1 dans le forum Bases de données
    Réponses: 2
    Dernier message: 28/11/2007, 14h11
  3. Suppression de doublons sur plusieurs champs
    Par riperoutz dans le forum Langage SQL
    Réponses: 3
    Dernier message: 05/02/2007, 14h23
  4. Réponses: 2
    Dernier message: 08/06/2006, 06h29
  5. [Hibernate] Héritage sur plusieurs niveaux
    Par srvremi dans le forum Hibernate
    Réponses: 2
    Dernier message: 31/05/2006, 18h39

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