Partage
  • Partager sur Facebook
  • Partager sur Twitter

Conseil, bonne pratique

    22 mai 2018 à 15:14:29

    Bonjour,

    j'essaye tant bien que mal de pouvoir soustraire à un calcul mensuelle les jours fériées selon les cas. 

    Cependant le champs jour fériée est un champs libre traité comme une chaîne de carractaire du type : 01/01/2018;02/04/2018;01/05/2018...

    Le souci c'est que mes modules n'ont pas forcement les mêmes jours fériées. 

    J'ai 2 table, une ou l'utilisateur renseigne les JF qu'il souhaite prendre en compte et une qui liste tout les JF de l'année. 

    Ce qu'il me manque c'est une fonction sql qui permet de faire une recherche du JF saisi dans la liste de JF de la table 2, il faut trouver des correspondances de façon generique. Ensuite il s'agit d'un case when que j'ai déjà :)

    N'hésitez pas à me proposer de meilleurs solutions si vous en avez !

    Par avance merci pour votre aide.

    -
    Edité par sakooo 22 mai 2018 à 15:16:41

    • Partager sur Facebook
    • Partager sur Twitter
      22 mai 2018 à 15:23:25

      Bonjour,

      sakooo a écrit:

      un champs libre traité comme une chaîne de carractaire du type : 01/01/2018;02/04/2018;01/05/2018

      Déjà pas bon ...

      Si tu traites des dates, utilises un champ de type DATE en base et assures-toi qu'il est correctement renseigné ...

      Une saisie manuelle dans un VARCHAR c'est la porte ouverte aux erreurs de saisie et de format ...

      Après je n'ai rien compris à ta demande ... Peux-tu clarifier un peu et donner des exemples de ce que tu fais, et de ce qui te gènes ?

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        22 mai 2018 à 15:32:25

        Benzouye a écrit:

        Une saisie manuelle dans un VARCHAR c'est la porte ouverte aux erreurs de saisie et de format ...

        Et pas que. C'est aussi se priver de toutes les fonctions de manipulation de date et de temps !



        • Partager sur Facebook
        • Partager sur Twitter
          22 mai 2018 à 15:36:09

          Oui c'est pas très clair, je te l'accorde haha. 

          Un utilisateur saisi une liste de date (JF) séparés par des point virgules enregistrer dans une table A, du type :

          JJ/MM/AAAA;JJ/MM/AAAA;JJ/MM/AAAA;JJ/MM/AAAA...

          Derrière j'ai une table B ou il y a la liste des JF sur l'année. 

          Il faudrait avoir une correspondance entre la table A et B, un simple like entre les 2 champs des 2 tables ne suffit pas car il ne retourne que les résultats identiques comme ceci : A.JF = B.JF (cela marche uniquement si l'utilisateur ne saisi qu'une seule date, vu que j'ai dans la table B une ligne par jour fériée)

          En réalité j'aurais besoin d'une fonction de balayage qui permet de chercher dans la chaîne de caractère de la table A, le ou les JF enregistré dans la table B.  

          Merci :)

          • Partager sur Facebook
          • Partager sur Twitter
            22 mai 2018 à 15:42:40

            sakooo a écrit:

            une liste de date (JF) séparés par des point virgules enregistrer dans une table A

            C'est exactement ça que je critiquais dans mon premier message ...

            Ce modèle n'est pas bon ... Il te faut stocker les jours distinctement dans la base de données ...

            Ton utilisateur choisi les jours dans un calendrier (selon le langage de programmation tu as des composant calendrier très bien), tu stockes ces jours en base, un enregistrement par jour ...

            • Partager sur Facebook
            • Partager sur Twitter
            Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
              22 mai 2018 à 16:01:31

              Benzouye a écrit:

              sakooo a écrit:

              une liste de date (JF) séparés par des point virgules enregistrer dans une table A

              C'est exactement ça que je critiquais dans mon premier message ...

              Ce modèle n'est pas bon ... Il te faut stocker les jours distinctement dans la base de données ...

              Ton utilisateur choisi les jours dans un calendrier (selon le langage de programmation tu as des composant calendrier très bien), tu stockes ces jours en base, un enregistrement par jour ...


              Alors la je suis preneur ca solutionnerais tous mes problèmes. 

              As-tu une idee pour le faire en sql ? avec autre chose que du SUBSTR 

              Merci :)

              • Partager sur Facebook
              • Partager sur Twitter
                22 mai 2018 à 16:05:40

                Il faut déjà réfléchir à ton modèle.

                Tu as des utilisateurs, des jours fériés. 2 entités = 2 tables.

                Un utilisateur peut choisir plusieurs jours fériés et un jour férié peut être choisi par plusieurs utilisateurs. C'est une relation n,n = 1 table.

                Le modèle serait du genre :

                • utilisateur ( id_utilisateur [pk], nom, prenom, etc. )
                • jour_ferie ( jour_ferie [pk] )
                • utilisateur_jour ( id_utilisateur [pk][fk], jour_ferie [pk][fk]

                Ensuite il faut modifier ton application pour ne plus faire saisir une chaîne de caractères à l'utilisateur, mais plutôt lui faire choisir (avec des cases à cocher par exemple) dans la liste des jours fériés possibles.

                Après, pour reprendre les données existantes, il faudrait savoir quel SGBD tu utilises, tous ne seront pas égaux devant le problème ...

                -
                Edité par Benzouye 22 mai 2018 à 16:11:44

                • Partager sur Facebook
                • Partager sur Twitter
                Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                  22 mai 2018 à 16:07:29

                  Benzouye a écrit:

                  Il faut déjà réfléchir à ton modèle.

                  Il te faut créer une table, du genre :

                  CREATE TABLE jour_ferie (
                      jour_ferie DATE,
                      PRIMARY KEY( jour_ferie )
                  );

                  Ensuite il faut modifier ton application pour ne plus faire saisir une chaîne de caractères à l'utilisateur, mais plutôt lui faire utiliser un composant calendrier. Je ne sais pas avec quel langage tu travailles ...

                  Après, pour reprendre les données existantes, il faudrait savoir quel SGBD tu utilises, tous ne seront pas égaux devant le problème ...

                  -
                  Edité par Benzouye il y a moins de 30s


                  Langage: PHP

                  SGBD : Oracle

                  • Partager sur Facebook
                  • Partager sur Twitter
                    22 mai 2018 à 16:12:21

                    Il faut déjà réfléchir à ton modèle.

                    Tu as des utilisateurs, des jours fériés. 2 entités = 2 tables.

                    Un utilisateur peut choisir plusieurs jours fériés et un jour férié peut être choisi par plusieurs utilisateurs. C'est une relation n,n = 1 table.

                    Le modèle serait du genre :

                    • utilisateur ( id_utilisateur [pk], nom, prenom, etc. )
                    • jour_ferie ( jour_ferie [pk] )
                    • utilisateur_jour ( id_utilisateur [pk][fk], jour_ferie [pk][fk]

                    Ensuite il faut modifier ton application pour ne plus faire saisir une chaîne de caractères à l'utilisateur, mais plutôt lui faire choisir (avec des cases à cocher par exemple) dans la liste des jours fériés possibles.

                    -
                    Edité par Benzouye 22 mai 2018 à 16:12:39

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                      22 mai 2018 à 16:27:46

                      Je ne suis pas -tout à fait- d'accord avec le modèle de Benzouye.

                      Dans l'absolue il a raison. Mais la liste des jours fériés n'est malheureusement pas une liste absolue. Au grès des décisions, certains jours peuvent être rajouté (et ça ne pose pas de problème), ou peuvent être retirés (et c'est le choix préféré de nos politiques, va savoir pourquoi... ^^).

                      Et là, quid des relations existantes avec un utilisateur si un jour férié devait disparaître ? Faut-il supprimer ces relations ? Faut-il les garder (mais ne plus permettre de choisir de tels jours à l'avenir ?) ? Les garder sous formes d'historique ?

                      @sakoo : il faut pousser plus loin ton cahier des charges et expliquer exactement à quoi servent ces sélections de dates.

                      Si on doit supprimer les relations, alors le modèle de Benzouye est le bon. Si ce n'est pas le cas, il faudra le modifier.

                      -
                      Edité par Sebajuste 22 mai 2018 à 16:28:00

                      • Partager sur Facebook
                      • Partager sur Twitter
                        23 mai 2018 à 12:17:30

                        Hello, pour information j'ai pu trouver une solution, j'enregistre ma chaîne de caractère au format ennoncé plus haut puis j'ai crée une vue matérialisé toute simple ayant pour but de découper ma chaîne afin de ne plus avoir:

                        "JJ/MM/YYYY;JJ/MM/YYYY;JJ/MM/YYYY;JJ/MM/YYYY..."

                        Mais : 

                        JJ/MM/YYYY

                        JJ/MM/YYYY

                        JJ/MM/YYYY

                        Voici la requete : 

                        SELECT regexp_substr(MA_DATA,'[^,]+', 1, level)
                        FROM MA_TABLE
                          CONNECT BY regexp_substr(MA_DATA, '[^,]+', 1, level) IS NOT NULL; 

                        Il faut renseigner ici le type de séparateur, ici il s'agit de virgule : [^,]

                        Merci à vous pour votre aide !!


                        • Partager sur Facebook
                        • Partager sur Twitter
                          23 mai 2018 à 13:10:25

                          Même si Oracle te permet d'éclater une chaîne, ce n'est pas une solution pertinente dans ton cas ... La requête de croisement entre les jours présents dans la table et cette regexp va être peu performante comparée à une jointure "normale" ...

                          Enfin bon ...

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                            23 mai 2018 à 15:22:59

                            sakooo a écrit:

                            Hello, pour information j'ai pu trouver une solution, j'enregistre ma chaîne de caractère au format ennoncé plus haut puis j'ai crée une vue matérialisé toute simple ayant pour but de découper ma chaîne


                            Non, non, non ! et re-non ! Ce que tu fais est criminel ! C'est une violation de la première forme normale, qui dit que tout attribut doit être atomique https://fr.wikipedia.org/wiki/Forme_normale_(bases_de_donn%C3%A9es_relationnelles)#1FN_–_Première_forme_normale (Et c'est criminel, car la prochaine personne qui va passer derrière toi pour apporter des modifications à ce système va immanquablement poster son problème sur un forum tel que celui-ci, où l'on va invariablement l'envoyer balader avec un "commence par normaliser ton modèle de données". Et personnellement, j'ai arrêté d'aider les personnes qui ne suivent pas la norme. Quand on sait où ça mène, c'est ma conscience éthique et morale qui m'oblige à ne pas donner de "conseil" pour faire de la merde).

                            Oracle (ou tout autre SGBDR) n'est pas un système de sauvegarde de données pour avoir de la persistance ! Un SGBDR réagit à des règles strictes de normalisation. Il FAUT les suivre pour avoir des données cohérentes, et exploitables. Ce n'est ni une option, ni négociable (au moins jusqu'à la troisième forme normale).

                            Autrement, utilise directement un simple fichier plat (et je déconne pas ! Ça peut être bien plus performant sur des données non normalisées). Ou à la limite une base de données NoSQL.

                            Mais sincèrement, avoir un topic de forum intitulé "Conseil, bonne pratique" qui se termine par "ma solution consiste à violer toutes notions de bonnes pratiques sur les SGBDR", c'est à vomir. Et je pèse mes mots. Je dis pas ça pour toi (si tu veux foncer dans le mur fonce...), mais pour le prochain visiteur qui dans un mois, un an ou plus, pourrait tomber sur ce topic. En l'état voici l'exemple typique de ce qu'il ne faut PAS faire, l'incarnation même de l'antithèse de la bonne pratique.

                            Mon post est violent, j'en conviens. Mais il a pour but de t'ouvrir les yeux sur le désastre vers lequel tu te dirige. C'est là mon seul conseil.

                            -
                            Edité par Sebajuste 23 mai 2018 à 15:23:52

                            • Partager sur Facebook
                            • Partager sur Twitter
                              31 mai 2018 à 13:08:08

                              Mea Culpa, 

                              Vous aviez raison, cette solution n'est pas la meilleur dans mon cas, elle n'est pas vivable sur le long terme...

                              J'ai pensé aux procédures stocker, est-ce une bonne idée ?

                              Merci messieurs.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                31 mai 2018 à 13:43:35

                                sakooo a écrit:

                                J'ai pensé aux procédures stocker, est-ce une bonne idée ?

                                Non plus ... Tu as lu ma première proposition ?

                                Benzouye a écrit:

                                Il te faut stocker les jours distinctement dans la base de données ...

                                Ton utilisateur choisi les jours dans un calendrier (selon le langage de programmation tu as des composant calendrier très bien), tu stockes ces jours en base, un enregistrement par jour ...

                                Ton modèle devrait être :

                                • jour_ferie ( date_ferie [pk] )
                                • utilisateur ( id [pk], nom, prenom, etc. )
                                • choix_jour ( id_utilisateur [pk][fk], date_ferie [pk][fk] )

                                Dans la table jour_ferie tu stockes tous les jours feriés possibles.

                                Dans la table utilisateur tu stockes tous les utilisateurs.

                                Dans ton application tu demandes à l'utilisateur de se connecter et tu mémorises son id.

                                Tu lui propose une liste des jours fériés présents dans la table jour_ferie, par exemple sous la forme d'un composant calendrier (genre jQuery Datepicker).

                                Lorsque l'utilisateur clique sur un jour dans le calendrier, tu insères dans la table choix_jour le couple id utilisateur / date férié.

                                Pour retrouver les jours fériés choisi par un utilisateur donné :

                                SELECT F.date_ferie
                                FROM
                                    jour_ferie F
                                        INNER JOIN choix_jour C
                                            ON F.date_ferie = C.date_ferie
                                WHERE C.id_utilisateur = 'id souhaité'

                                Pour retrouver les jours que n'a pas choisi un utilisateur donné :

                                SELECT F.date_ferie
                                FROM
                                    jour_ferie F
                                        LEFT JOIN choix_jour C
                                            ON F.date_ferie = C.date_ferie
                                            AND C.id_utilisateur = 'id souhaité'
                                WHERE C.date_ferie IS NULL

                                -
                                Edité par Benzouye 31 mai 2018 à 13:43:59

                                • Partager sur Facebook
                                • Partager sur Twitter
                                Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL

                                Conseil, bonne pratique

                                × 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