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

Diagrammes de Classes Discussion :

Avis pour améliorer un diagramme de classe


Sujet :

Diagrammes de Classes

  1. #41
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Diégane,



    Citation Envoyé par mossane Voir le message
    C'est bien ce que veut la règle. Aussi, je propose les deux triggers suivants
    Les triggers paraissent tout à fait sympathiques, le codage correct du point de vue relationnel, le problème est que MySQL ne l’entend pas de cette oreille : La variable @N1 ne prend pas la valeur de CorpsTypeId, mais une valeur qui en tout cas n’est pas scalaire... La comparaison de @N1 et @N2 semble donner quelque chose comme null, que l’on utilise l’égalité ou l’inégalité : l’erreur n’est donc pas déclenchée. J’ai fouillé dans la doc, mais n’ai pas trouvé la solution.

    J’ai essayé de ne pas utiliser de variable :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    IF     (SELECT CORPS.CorpsTypeId AS a                 
            FROM   TEXTE_CORPS_TYPE_CORPS INNER JOIN CORPS 
                   ON TEXTE_CORPS_TYPE_CORPS.CorpsId = CORPS.CorpsId 
            WHERE  TEXTE_CORPS_TYPE_CORPS.CorpsId = NEW.CorpsId
              AND  TEXTE_CORPS_TYPE_CORPS.TexteId = New.TexteId)
        <> 
           (SELECT TEXTE_CORPS_TYPE.CorpsTypeId AS b
            FROM   TEXTE_CORPS_TYPE_CORPS INNER JOIN TEXTE_CORPS_TYPE
                   ON TEXTE_CORPS_TYPE_CORPS.TexteId = TEXTE_CORPS_TYPE.TexteId
            WHERE  TEXTE_CORPS_TYPE_CORPS.CorpsId = NEW.CorpsId
              AND  TEXTE_CORPS_TYPE_CORPS.TexteId = New.TexteId)
        THEN
            SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = 'merdum !' ;
    END IF ;

    Mais peine perdue, MySQL et la comparaison d’expressions de tables ça fait deux...


    J’ai essayé d’utiliser une table temporaire à une ligne et deux colonnes pour stocker le résultat de chaque SELECT : même punition.

    La question est donc : comment affecter à une variable scalaire la valeur d’une cellule (une colonne, une ligne) d’une table ? Pour le moment je n’ai pas de réponse, mais je vais continuer à fouiller, je vais essayer le SELECT INTO...



    Citation Envoyé par mossane Voir le message
    Peut-être que je me trompe, mais j'ai l'impression que dans une structure, un projet ne pourra pas revêtir un même état plus d'une fois. Du fait de la clé primaire constituée du triplet (ProjetId, StructureId, EtatId) dans PROJET_ETAT_STRUCTURE, dans une structure s1, un projet p1 ne pourra pas être repris (état e1) plusieurs fois par exemple.

    Est-ce bien le cas ?
    C’est bien le cas. Si dans la structure s1, le projet p1 doit pouvoir être repris plus d’une fois lorsqu’il est dans l’état disons e1, alors l’attribut EtatDate devrait entrer dans la composition de la clé.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  2. #42
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    En fait, le trigger fonctionne, ouf ! Mais il fallait simplifier les SELECT, car on effectuait une jointure avec la table TEXTE_CORPS_TYPE_CORPS, en fonction de valeurs non encore présentes. Je me suis fait avoir comme un bleu, une contrainte au sens relationnel ne se plaque pas telle quelle dans un trigger ...

    La bonne version :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    CREATE TRIGGER TEXTE_CORPS_TYPE_CORPS_BEFORE_INSERT BEFORE INSERT ON TEXTE_CORPS_TYPE_CORPS 
    FOR EACH ROW 
    BEGIN
    SET @N1 =  (
                SELECT CorpsTypeId             
                FROM   CORPS
                WHERE  CorpsId = NEW.CorpsId
               ) ;
    SET @N2 =  (
                SELECT CorpsTypeId
                FROM   TEXTE_CORPS_TYPE
                WHERE  TexteId = New.TexteId
               ) ;
    IF @N1 <>  @N2  THEN
        SET @T = CONCAT('Echec : le corps  ', 
                         NEW.CorpsId, '  référence le texte ', 
                         NEW.TexteId, ' qui détermine un cadre incompatible');
        SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = @T; 
    END IF;
    END

    Plus simple, non ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  3. #43
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    En plus, pauvre MySQL, j'ai été bien médisant, car le code ci-dessous fonctionne aussi...


    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    CREATE TRIGGER TEXTE_CORPS_TYPE_CORPS_BEFORE_INSERT BEFORE INSERT ON TEXTE_CORPS_TYPE_CORPS 
    FOR EACH ROW 
    BEGIN
     IF    (SELECT CorpsTypeId             
            FROM   CORPS
            WHERE  CorpsId = NEW.CorpsId)
        <> 
           (SELECT CorpsTypeId
            FROM  TEXTE_CORPS_TYPE
    	WHERE TexteId = New.TexteId)
        THEN
           SET @T = CONCAT('Echec : le corps  ', 
                            NEW.CorpsId, ' référence le texte', 
                            NEW.TexteId, ' qui détermine un cadre incompatible');
           SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = @T; 
    END IF ;
    END
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  4. #44
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonsoir François,

    J'ai mis du temps. J'étais en train de faire un récapitulatif de ce qu'on a fait depuis le début.

    Citation Envoyé par fsmrel Voir le message
    La bonne version :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    CREATE TRIGGER TEXTE_CORPS_TYPE_CORPS_BEFORE_INSERT BEFORE INSERT ON TEXTE_CORPS_TYPE_CORPS 
    FOR EACH ROW 
    BEGIN
    SET @N1 =  (
                SELECT CorpsTypeId             
                FROM   CORPS
                WHERE  CorpsId = NEW.CorpsId
               ) ;
    SET @N2 =  (
                SELECT CorpsTypeId
                FROM   TEXTE_CORPS_TYPE
                WHERE  TexteId = New.TexteId
               ) ;
    IF @N1 <>  @N2  THEN
        SET @T = CONCAT('Echec : le corps  ', 
                         NEW.CorpsId, '  référence le texte ', 
                         NEW.TexteId, ' qui détermine un cadre incompatible');
        SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = @T; 
    END IF;
    END

    Plus simple, non ?
    Oui, c'est beaucoup plus simple.

    Hormis les classes COLLEGE, FONCTION et GROUPE, si nous récapitulons ce qu'on a fait depuis le début, voici ce que nous obtenons.

    Nom : mcd.jpg
Affichages : 1643
Taille : 215,9 Ko

    C'est énorme ! A moi tout seul, jamais je n'aurai espéré obtenir un tel résultat.

    Citation Envoyé par fsmrel Voir le message
    Je vais regarder de plus près la partie CIRCUIT, STRUCTURE, ETAT, car il y a des contraintes de chemin en perspective à mettre en œuvre : par exemple, un projet p1 fait référence à un circuit c1, lequel peut faire référence aux structures s1 et s2, tandis que par la relation entre PROJET et STRUCTURE, p1 peut faire référence à d’autres structures, par exemple s3 et s4.

    De même, via la classe PROJET_ETAT_STRUCTURE, ce même projet p1 peut être associé aux structures s5 et s6... Par ailleurs, pour un projet et une structure donnés, peut-on avoir plus d’un état ?
    J'espère que les triggers suivants feront l'affaire.

    TABLE : PROJET_STRUCTURE
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    CREATE TRIGGER PROJET_STRUCTURE_BEFORE_INSERT BEFORE INSERT ON PROJET_STRUCTURE FOR EACH ROW
    BEGIN
    	SET @N1 = (
    				SELECT CircuitId 
                                    FROM PROJET
                                    WHERE ProjetId = NEW.ProjetId
    			);
    	SET @N2 = (
    				SELECT CircuitId
                                    FROM CIRCUIT_STRUCTURE
                                    WHERE StructureId = NEW.StructureId
    			);
    	IF @N1 <> @N2 THEN
    		SET @T = CONCAT('Echec : le projet ',
    					   NEW.ProjetId, ' référence la structure ',
                                               NEW.StructureId, ' qui ne fait pas partie de son circuit'
    					  );
    		SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = @T;
    	END IF;
    END;

    TABLE : PROJET_STRUCTURE_ETAT
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    CREATE TRIGGER PROJET_ETAT_STRUCTURE_BEFORE_INSERT BEFORE INSERT ON PROJET_ETAT_STRUCTURE FOR EACH ROW
    BEGIN
    	SET @N1 = (
    				SELECT CircuitId 
                                    FROM PROJET
                                    WHERE ProjetId = NEW.ProjetId
    			);
    	SET @N2 = (
    				SELECT CircuitId
                                    FROM CIRCUIT_STRUCTURE
                                    WHERE StructureId = NEW.StructureId
    			);
    	IF @N1 <> @N2 THEN
    		SET @T = CONCAT('Echec : le projet ',
    					   NEW.ProjetId, ' référence la structure ',
                                               NEW.StructureId, ' qui ne fait pas partie de son circuit'
    					  );
    		SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = @T;
    	END IF;
    END;

    J'ai opéré quelques réaménagements. J'ai fait hériter les classes AGENT_PERMANENT et AGENT_TEMPORAIRE de la classe AGENT. En effet,un agent permanent est un agent titularisé dans un corps par nomination ou engagement. C'est un agent qui a bénéficié d'un acte au moins une fois. Il peut avancer en échelons et en classes.
    Par contre, un agent temporaire (un vacataire par exemple) est un agent que l'on peut certes classer dans un corps, mais qui n'a pas encore été titularisé dans cette fonction. C'est un agent qui n'a jamais bénéficié d'acte. Il est affecté par ordre de service. Il ne peut avancer ni en échelons, ni en classes.

    J'ai introduit une classe COURRIER, car le déclenchement de certains projets se fait à la suite d'un courrier envoyé par l'intéressé. Cependant, d'autres projets peuvent être déclenchés sans courrier. Certes, on ne peut pas parler du type d'un courrier (décret, arrêté, etc.), mais il a bien un objet. Un projet issu d'un courrier partage le même objet avec ce courrier.

    La classe REDACTEUR nous permet de garder une trace de l'initiateur d'un projet. Bien qu'un rédacteur soit un agent permanent, je n'ai pas jugé nécessaire de faire hériter la classe REDACTEUR de la classe AGENT_PERMANENT. J'ai usé de la réflexivité pour matérialiser le fait qu'un rédacteur travaille dans un bureau qui se trouve dans une division qui se trouve elle-même dans une direction, etc.

    J'ai ajouté un attribut StructureOrdre dans PROJET_STRUCTURE pour définir l'ordre dans lequel un projet traverse les structures de son circuit. Cet attribut sera ajouté à la clé primaire de la structure dérivée pour permettre à un projet de passer plus d'une fois dans une même structure de son circuit de validation.

    L'attribut TexteType de la classe TEXTE a été promue en classe TEXTE_TYPE et la classe CORPS_TYPE a été renommée en CATEGORIE.

    Citation Envoyé par fsmrel Voir le message
    Pour plus de flexibilité, j'ai promu l'attribut Lieu en classe SERVICE. Ici également, j'ai usé de la réflexivité pour hiérarchiser les différents services de l'administration.

    Fort de tous ces changements, j'en ai déduit la structure dérivée suivante.

    Nom : mld.jpg
Affichages : 1309
Taille : 302,7 Ko

    Je ne sais pas si c'est la meilleure solution, mais j'ai retenu le couplet (AgentId, ActeId) comme clé primaire de la classe AGENT_ECHELON. De même, le couplet (AgentId, OrdreServiceId) servira de clé primaire à la classe AGENT_CORPS.

    J'ai beaucoup appris avec vous dans cette discussion François. Je m'étais déjà habitué à échanger avec vous, mais je ne voudrais plus abuser de votre disponibilité plus longtemps. L'essentiel a été fait. Aussi, une fois que cette dernière structure dérivée sera validée, je voudrai avec votre permission marquer la discussion comme étant résolue.

    Un grand merci à vous François. Je vous souhaite de passer de bonnes fêtes de Noël.

  5. #45
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Diégane,


    Citation Envoyé par mossane Voir le message
    J'ai mis du temps. J'étais en train de faire un récapitulatif de ce qu'on a fait depuis le début.
    Il vaut miex prendre son temps et bâtir des fondations robustes sur lesquelles un système pourra évoluer sans problème. Trop de gens s’excitent à échaffauder dans la précipitation l’imprécision et l’incomplétude (souvent sous la pression de la hiérarchie), pour finir par devoir mettre leur modèle à la poubelle et recommencer.

    Naf-Naf a mis plus de temps que Nif-Nif et Nouf-Nouf pour construire sa maison, mais c’était un sage, et qui savait prévoir...







    Citation Envoyé par mossane Voir le message
    J'ai fait hériter les classes AGENT_PERMANENT et AGENT_TEMPORAIRE de la classe AGENT.
    Voilà une preuve que, sur des fondations saines, on peut prendre en compte une règle au fond pas si simple, mais sans rien casser. N’oubliez pas au stade SQL de mettre en œuvre un trigger interdisant qu’un agent puisse être à la fois permanent et temporaire car, lors d’un changement (favorable !) de situation d’un agent, l’application pourrait oublier de faire le ménage et laisser s’installer l’ambivalence, (encore un truc à affaiblir une base de données...)



    Table PROJET_POSTULANT_COURRIER

    Selon le diagramme de classes, le lien connectant COURRIER à PROJET_POSTULANT est porteur d’une multiplicité 0..1, en conséquence de quoi, à l’étage SQL, l’attribut Courrier de la table PROJET_POSTULANT_COURRIER doit faire l’objet d’une clé candidate.



    Citation Envoyé par mossane Voir le message
    J'ai usé de la réflexivité pour matérialiser le fait qu'un rédacteur travaille dans un bureau qui se trouve dans une division qui se trouve elle-même dans une direction, etc.
    D’accord. Si MySQL vou pose des problèmes pour gérer la récursivité, n’hésitez pas à le faire savoir. MySQL ne connaît pas la fermeture transitive, donc vous aurez à mettre en œuvre une procédure récursive, mais ça n’est quand même pas la mer à boire...



    Citation Envoyé par mossane Voir le message
    J'ai ajouté un attribut StructureOrdre dans PROJET_STRUCTURE pour définir l'ordre dans lequel un projet traverse les structures de son circuit. Cet attribut sera ajouté à la clé primaire de la structure dérivée pour permettre à un projet de passer plus d'une fois dans une même structure de son circuit de validation.
    Nihil obtat. Cela dit, l’attribut StructureOrdre apparaît seulement dans le MLD, pas dans le diagramme de classes. De même la table PROJET_STRUCTURE_ETAT devrait en hériter : pas vu dans le MLD.



    Citation Envoyé par mossane Voir le message
    L'attribut TexteType de la classe TEXTE a été promue en classe TEXTE_TYPE et la classe CORPS_TYPE a été renommée en CATEGORIE.
    Pas de problème.


    Citation Envoyé par mossane Voir le message
    Pour plus de flexibilité, j'ai promu l'attribut Lieu en classe SERVICE. Ici également, j'ai usé de la réflexivité pour hiérarchiser les différents services de l'administration.
    Ça marche !



    Citation Envoyé par mossane Voir le message
    Je ne sais pas si c'est la meilleure solution, mais j'ai retenu le couplet (AgentId, ActeId) comme clé primaire de la classe AGENT_ECHELON.
    De mémoire, la paire {AgentId, EchelonId} est clé candidate. Si c’est bien le cas, que la paire {AgentId, ActeId} soit élue Miss clé primaire, pas de problème, mais {AgentId, EchelonId} n’en est pas moins dauphine : elle devra bien faire l’objet d’une clause UNIQUE au stade SQL (CREATE TABLE). Merci d’apporter des précisions sur ce point.


    Citation Envoyé par mossane Voir le message
    De même, le couplet (AgentId, OrdreServiceId) servira de clé primaire à la classe AGENT_CORPS.
    Même remarque.



    Citation Envoyé par mossane Voir le message
    J'ai beaucoup appris avec vous dans cette discussion François. Je m'étais déjà habitué à échanger avec vous, mais je ne voudrais plus abuser de votre disponibilité plus longtemps. L'essentiel a été fait. Aussi, une fois que cette dernière structure dérivée sera validée, je voudrai avec votre permission marquer la discussion comme étant résolue.
    Je regretterai de plus échanger avec vous... Il est bien rare que les concepteurs présentent leur sujet avec autant de clarté, rigueur, précision et intelligence. En quarante ans, il est un fait que j’en ai bien peu rencontré présentant ces qualités.


    Je vous souhaite un saint et joyeux Noël,

    François
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  6. #46
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonjour François,

    Citation Envoyé par fsmrel Voir le message
    N’oubliez pas au stade SQL de mettre en œuvre un trigger interdisant qu’un agent puisse être à la fois permanent et temporaire car, lors d’un changement (favorable !) de situation d’un agent, l’application pourrait oublier de faire le ménage et laisser s’installer l’ambivalence, (encore un truc à affaiblir une base de données...)
    Étant donné qu'un agent ne peut être à la fois permanent et temporaire, le changement de situation d'un agent temporaire vers celui d'agent permanent impliquerait d'abord, la suppression de ce dernier de la table AGENT_TEMPORAIRE avant son ajout dans la table AGENT_PERMANENT. A mon avis, il serait peut être intéressant de conserver une trace du passé d'agent temporaire d'un agent devenu permanent. Ainsi, au lieu de les supprimer, je pense que l'on peut mettre en place un système d'archivage par ajout d'un attribut Promu dans la Table AGENT_TEMPORAIRE qui aura la valeur FALSE par défaut. Cet attribut passera à TRUE dès le changement de statut d'un agent. Ce qui nous donne les triggers suivants.

    TABLE : AGENT_PERMANENT
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    CREATE TRIGGER AGENT_PERMANENT_BEFORE_INSERT BEFORE INSERT ON AGENT_PERMANENT FOR EACH ROW
    BEGIN
    	SET @N = (
    				SELECT COUNT(*)
                                    FROM AGENT_TEMPORAIRE
                                    WHERE AgentId = NEW.AGENTId
    		       );
    	IF @N > 0 THEN
    		UPDATE AGENT_TEMPORAIRE
                    SET Promu = TRUE
                    WHERE AgentId = NEW. AGENTId;
    	END IF;
    END;

    TABLE : AGENT_TEMPORAIRE
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    CREATE TRIGGER AGENT_TEMPORAIRE_BEFORE_INSERT BEFORE INSERT ON AGENT_TEMPORAIRE FOR EACH ROW
    BEGIN
    	SET @N = (
    				SELECT COUNT(*)
                                    FROM AGENT_PERMANENT
                                    WHERE AGENTId = NEW.AGENTId
    		       );
    	IF @N > 0 THEN
    		SET @T = CONCAT ('Echec d''ajout d''un agent temporaire : un agent permanent existe déjà pour l''attribut AgentId égal à ', NEW.AgentId) ; 
                    SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = @T;
    	END IF;
    END;

    Je ne sais pas s'il est pertinent de le faire, vu que la table EX_AGENT existe déjà. Mais je pense utiliser la même technique en ajoutant un attribut Actif à la table AGENT_PERMANENT, qui sera cette fois ci positionné par défaut à TRUE. Il passera à FALSE dès qu'un agent quitte l'administration.

    Citation Envoyé par mossane Voir le message
    TABLE : PROJET_STRUCTURE
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    CREATE TRIGGER PROJET_STRUCTURE_BEFORE_INSERT BEFORE INSERT ON PROJET_STRUCTURE FOR EACH ROW
    BEGIN
    	SET @N1 = (
    				SELECT CircuitId 
                                    FROM PROJET
                                    WHERE ProjetId = NEW.ProjetId
    			);
    	SET @N2 = (
    				SELECT CircuitId
                                    FROM CIRCUIT_STRUCTURE
                                    WHERE StructureId = NEW.StructureId
    			);
    	IF @N1 <> @N2 THEN
    		SET @T = CONCAT('Echec : le projet ',
    					   NEW.ProjetId, ' référence la structure ',
                                               NEW.StructureId, ' qui ne fait pas partie de son circuit'
    					  );
    		SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = @T;
    	END IF;
    END;

    TABLE : PROJET_STRUCTURE_ETAT
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    CREATE TRIGGER PROJET_ETAT_STRUCTURE_BEFORE_INSERT BEFORE INSERT ON PROJET_ETAT_STRUCTURE FOR EACH ROW
    BEGIN
    	SET @N1 = (
    				SELECT CircuitId 
                                    FROM PROJET
                                    WHERE ProjetId = NEW.ProjetId
    			);
    	SET @N2 = (
    				SELECT CircuitId
                                    FROM CIRCUIT_STRUCTURE
                                    WHERE StructureId = NEW.StructureId
    			);
    	IF @N1 <> @N2 THEN
    		SET @T = CONCAT('Echec : le projet ',
    					   NEW.ProjetId, ' référence la structure ',
                                               NEW.StructureId, ' qui ne fait pas partie de son circuit'
    					  );
    		SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = @T;
    	END IF;
    END;
    En parlant de triggers, est-ce que ceux que j'ai proposés pour la gestion des contraintes de chemin entre PROJET, PROJET_STRUCTURE et PROJET_STRUCTURE_ETAT sont corrects ?

    J'en profite également pour renforcer la cohérence des données entre COURRIER et PROJET d'une part, et PROJET et ACTE d'autre part. Lorsqu'un acte fait référence à un projet, il doit avoir le même objet et doit être du même type que ce projet. Idem entre PROJET et COURRIER.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    CREATE TRIGGER ACTE_RECENT_BEFORE_INSERT BEFORE INSERT ON ACTE_RECENT FOR EACH ROW
    BEGIN
    	SET @N1 = (
    				SELECT TypeId
                                    FROM PROJET
                                    WHERE ProjetId = NEW.ProjetId
    			  );
    	SET @N2 = (
    				SELECT TypeId
                                    FROM ACTE
                                    WHERE ActeId = NEW.ActeId
    			  );
    	IF @N1 = @N2 THEN
    		SET @N3 = (
    					SELECT ObjetId 
                                            FROM PROJET
                                            WHERE ProjetId = NEW.ProjetId
    				 );
    		SET @N4 = (
    					SELECT ObjetId
                                            FROM ACTE
                                            WHERE ActeId = NEW.ActeId
    				  );
    		IF @N3 != @N4 THEN
    			SET @T = CONCAT('Echec : l''acte ', NEW.ActeId, ' doit avoir le même objet que le projet ', NEW.ProjetId);
                            SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = @T;
    		END IF;
    	ELSE
    		SET @T = CONCAT('Echec : l''acte ', NEW.ActeId, ' doit être du même type que le projet ', NEW.ProjetId);
                    SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = @T;
    	END IF;
    END;

    Un trigger similaire sera rattaché à la table PROJET_POSTULANT_COURRIER.

    Citation Envoyé par fsmrel Voir le message
    Table PROJET_POSTULANT_COURRIER

    Selon le diagramme de classes, le lien connectant COURRIER à PROJET_POSTULANT est porteur d’une multiplicité 0..1, en conséquence de quoi, à l’étage SQL, l’attribut Courrier de la table PROJET_POSTULANT_COURRIER doit faire l’objet d’une clé candidate.
    J'en ferai une clé candidate.

    Citation Envoyé par fsmrel Voir le message
    D’accord. Si MySQL vou pose des problèmes pour gérer la récursivité, n’hésitez pas à le faire savoir. MySQL ne connaît pas la fermeture transitive, donc vous aurez à mettre en œuvre une procédure récursive, mais ça n’est quand même pas la mer à boire...
    Je vais me renseigner davantage sur le sujet.

    Citation Envoyé par fsmrel Voir le message
    Nihil obtat. Cela dit, l’attribut StructureOrdre apparaît seulement dans le MLD, pas dans le diagramme de classes. De même la table PROJET_STRUCTURE_ETAT devrait en hériter : pas vu dans le MLD.
    Pour classe PROJET_STRUCTURE, c'est un oubli de ma part. Pour la table PROJET_STRUCTURE_ETAT, merci de me l'avoir rappelé.

    Citation Envoyé par fsmrel Voir le message
    De mémoire, la paire {AgentId, EchelonId} est clé candidate. Si c’est bien le cas, que la paire {AgentId, ActeId} soit élue Miss clé primaire, pas de problème, mais {AgentId, EchelonId} n’en est pas moins dauphine : elle devra bien faire l’objet d’une clause UNIQUE au stade SQL (CREATE TABLE). Merci d’apporter des précisions sur ce point.
    Je viens de m'en rendre compte. Je pense qu'en faisant de la paire {AgentId, EchelonId} une clé candidate, nous nous exposons à un petit problème. Imaginons qu'à travers l'acte a1, l'agent ag1 accède à l'échelon e1 de la première classe du corps des instituteurs. Il est possible, à travers l'acte a2, que ce même agent (ag1) aille à la retraite à cet échelon e1 (même classe, même corps). Du coup, on se retrouve avec un doublon que la clé candidate {AgentId, EchelonId} ne saurait accepter. Par contre, la paire {AgentId, ActeId} sera toujours unique. N'est-ce pas que le triplet {AgentId, ActeId, EchelonId} peut bien jouer le rôle d'une clé primaire ?

    Citation Envoyé par fsmrel Voir le message
    Je regretterai de plus échanger avec vous... Il est bien rare que les concepteurs présentent leur sujet avec autant de clarté, rigueur, précision et intelligence. En quarante ans, il est un fait que j’en ai bien peu rencontré présentant ces qualités.
    Tous les regrets sont pour moi. A chacun de vos messages, j'ai appris quelque chose de nouveau. Les réponses étaient si claires, le chemin si bien balisé qu'il m'était relativement facile de me rectifier et d'adapter mon travail à la nouvelle donne. Tout le mérite vous revient François.

    Merci !

  7. #47
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonjour François,

    J'ai du opérer de nouveaux réaménagements pour prendre en compte des considérations de dernière minute. J'avais déjà distingué deux catégories d'agents (permanents et temporaires). Il se trouve que chacune de ces catégories comporte également des sous-catégories.

    Nom : mcd2.jpg
Affichages : 2130
Taille : 131,2 Ko

    Parmi les agents permanents, il y a ceux que j'ai appelé agents permanents titulaires et les agents permanents contractuels. Un agent permanent titulaire est un agent qui a été titularisé dans un corps et qui a la qualification professionnelle requise pour occuper une telle fonction. Il avance d'échelon à échelon et de classe à classe. Un agent permanent contractuel est par contre un agent auquel l'administration fait appel pour palier un déficit d'agents dans un corps donné. Il n'a pas encore tous les diplômes professionnels requis pour exercer la fonction. En attendant de valider ses diplômes et d'être titularisé dans le corps de référence, l'agent permanent contractuel est en contrat à durée indéterminée avec l'administration et est classé dans un corps de contractuels. Il peut aller à la retraite avec ce statut s'il ne parvient pas à valider se diplômes dans les délais qui lui sont fixés. Il avance de catégorie à catégorie. On ne fera pas de distinction entre classe et catégorie.

    On retrouve aussi des titulaires et des contractuels parmi les agents temporaires. Ceux que j'ai appelé agents temporaires titulaires sont généralement les sortants de certaines écoles de formation qui sont intégrés d'office dans l'administration. Même s'il est bien placé dans son corps d'appartenance, l'agent temporaire titulaire est considéré pour ses premières années comme un stagiaire. Il ne bénéficie pas d'avancements. Il est quand même appelé à être titularisé un jour ou l'autre. Les agents temporaires titulaires sont les seuls à être affectés par ordre de service. Un agent temporaire contractuel est quant à lui en contrat à durée déterminée. Il quitte l'administration à la fin du contrat s'il n'est pas renouvelé.

    J'ai juste repris la partie concernée par les réaménagement. J'espère que la conception tient toujours.

    Merci !

  8. #48
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Diégane,


    Pour le moment je suis pas mal pris, mais j’essaierai de trouver un peu de temps pour vérifier les triggers et tout ça. En vitesse :


    Citation Envoyé par mossane Voir le message
    A mon avis, il serait peut être intéressant de conserver une trace du passé d'agent temporaire d'un agent devenu permanent. Ainsi, au lieu de les supprimer, je pense que l'on peut mettre en place un système d'archivage par ajout d'un attribut Promu dans la Table AGENT_TEMPORAIRE qui aura la valeur FALSE par défaut. Cet attribut passera à TRUE dès le changement de statut d'un agent.
    Fonctionnellement, pas de problème, et pour leur part, les triggers ont une bonne tête...


    Citation Envoyé par mossane Voir le message
    Je ne sais pas s'il est pertinent de le faire, vu que la table EX_AGENT existe déjà. Mais je pense utiliser la même technique en ajoutant un attribut Actif à la table AGENT_PERMANENT, qui sera cette fois ci positionné par défaut à TRUE. Il passera à FALSE dès qu'un agent quitte l'administration.
    Suite logique de ce qui précède, pas de problème si vous voulez conserver la trace du passé d’un agent ayant quitté l’administration.


    En attendant, je vois que vous arrivez à bien vous tirer d’affaire !


    Je vous souhaite une bonne année 2015,


    François
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  9. #49
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonjour François,

    Citation Envoyé par fsmrel Voir le message
    Pour le moment je suis pas mal pris, mais j’essaierai de trouver un peu de temps pour vérifier les triggers et tout ça.
    Prenez tout votre temps.

    Bonne et heureuse année 2015.

    Merci !

  10. #50
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonjour François,

    Grâce à vous, j'ai pu obtenir un résultat inespéré. Le projet a été bâti sur de bonnes bases. Aussi, je me sens suffisamment armé pour le mener à bon port. Soyez donc rassuré ! Je ne saurais trop vous remercier pour tout l'appui que vous m'avez accordé.

    Merci et plein de réussite à vos projets.

+ Répondre à la discussion
Cette discussion est résolue.
Page 3 sur 3 PremièrePremière 123

Discussions similaires

  1. Réponses: 10
    Dernier message: 20/06/2017, 14h43
  2. avis pour améliorer mon diagramme de classe: gestion des sujets PFE
    Par win_ubuntu dans le forum Diagrammes de Classes
    Réponses: 0
    Dernier message: 12/08/2014, 21h35
  3. Réponses: 30
    Dernier message: 05/08/2009, 19h25
  4. [CV] Avis pour améliorer mon cv
    Par lapanne dans le forum CV
    Réponses: 7
    Dernier message: 17/10/2007, 15h04
  5. Réponses: 2
    Dernier message: 17/10/2006, 23h55

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