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

PL/SQL Oracle Discussion :

Procédure de traitement si année est bisextile


Sujet :

PL/SQL Oracle

  1. #1
    Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 48
    Points : 43
    Points
    43
    Par défaut Procédure de traitement si année est bisextile
    Bonjour,

    je veux faire un traitement sur le nombre de jour créditeur et le nombre de jour débiteur et avant je dois créer une fonction ou bien une procedure qui fait ce traitment si quelqu'un parmi vous peut m'aider..

    Merci;

  2. #2
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    pour savoir si une année est bisextile :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    create or replace function IsBisextile(year in number) 
     return number
     is
       res number;
     begin
       if ((mod(year, 4) = 0) and ((mod(year,10) != 0) or (mod(year, 400) = 0))) then
         res := 1;
       else
         res := 0;
       end if;
     
       return res;
     end;
     /
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  3. #3
    Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 48
    Points : 43
    Points
    43
    Par défaut Procédure de traitement si année est bisextile
    Merci infiniment je vais utiliser cette fonction.

  4. #4
    Membre actif Avatar de JerryMouse
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    215
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 215
    Points : 295
    Points
    295
    Par défaut
    Tu peux faire le test juste si le dernier jour du mois de février de cette année est 29.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE OR REPLACE FUNCTION IsBisextile(year IN number) Return Boolean IS
    Begin
       If To_Char(Last_Day(To_Date('0102'||LPad(year,4,'0'))),'DD')=29 Then
        Return True;
       End if;
       Return False;
    End;
     /
    Très souvent, le plus difficile est de savoir ce que l'on veut.

  5. #5
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Tu penses réellement qu'un to_char() + last_day() + to_date() + lpad() est plus simple et plus performant que 3 modulo ???


    Citation Envoyé par JerryMouse Voir le message
    Tu peux faire le test juste si le dernier jour du mois de février de cette année est 29.
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  6. #6
    Membre actif Avatar de JerryMouse
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    215
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 215
    Points : 295
    Points
    295
    Par défaut
    Ça m'évite au moins de mémoriser les règles de calcul d'une année bisextile
    Très souvent, le plus difficile est de savoir ce que l'on veut.

  7. #7
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Citation Envoyé par JerryMouse Voir le message
    Ça m'évite au moins de mémoriser les règles de calcul d'une année bisextile
    C'est bien pour cette raison que l'on des crée des fonctions... non ?

    Maintenant, avec ton raisonnement, on crée des applis qui rament seulement parce que l'on sait pas comment faire et que l'on va au plus court en laissant de côté les perfs...

    Tu gagnes 5 minutes en conception et tu perds un temps conséquent en exécution... Je doute que le client et les utilisateurs partagent ton point de vue.
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  8. #8
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    de toute façon la fonction est fausse

    elle devrait s'appeler IsBisSextile

    plus sérieusement, c'est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (mod(year,100) <> 0 OR mod(year, 400) = 0)
    100 et pas 10

    Du coup :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CREATE OR REPLACE FUNCTION IsBissextile(year IN number) 
     RETURN number
     IS
       res number;
     begin
       IF (mod(year, 4) = 0 AND (mod(year,100) != 0 OR mod(year, 400) = 0)) then
         res := 1;
       else
         res := 0;
       end IF;
     
       RETURN res;
     end;
     /
    SQL> select IsBissextile(&a) from dual;
    Enter value for a: 2004
    old 1: select IsBissextile(&a) from dual
    new 1: select IsBissextile(2004) from dual

    ISBISSEXTILE(2004)
    ------------------
    1

    SQL> /
    Enter value for a: 2000
    old 1: select IsBissextile(&a) from dual
    new 1: select IsBissextile(2000) from dual

    ISBISSEXTILE(2000)
    ------------------
    1

    SQL> /
    Enter value for a: 2010
    old 1: select IsBissextile(&a) from dual
    new 1: select IsBissextile(2010) from dual

    ISBISSEXTILE(2010)
    ------------------
    0

    SQL> /
    Enter value for a: 2100
    old 1: select IsBissextile(&a) from dual
    new 1: select IsBissextile(2100) from dual

    ISBISSEXTILE(2100)
    ------------------
    0

  9. #9
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    yep...

    Le pire c'est que j'ai repris un de mes code C que j'ai adapté en PL avant de poster..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int isLeapYear(int year)
    {
      return ((year % 4) == 0) && ((year % 100 != 0) || (year % 400 == 0));
    }
    en remplacant les % par des mod, j'ai bouffé un 0...

    En tout cas, merci Fred, tu veilles toujours au grain
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  10. #10
    Membre actif Avatar de JerryMouse
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    215
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 215
    Points : 295
    Points
    295
    Par défaut
    Beuh! Simplicité ou complexité... c'est relatif.
    Si on me demain ce que c'est qu'une année bissextile je préfère ne pas avoir à expliquer que
    c'est une année multiple de 4 qui n'est pas multiple de 10 ou qui est multiple de 400
    Alors que pour moi c'est plus simple de dire que
    c'est une année dont la mois de février compte 29 jours .
    d'autant plus qu'Oracle est déjà allé loin au niveau gestion des dates. pourquoi alors refaire des calculs là ou le résultat est disponible. c'est ça aussi la modularité.
    Très souvent, le plus difficile est de savoir ce que l'on veut.

  11. #11
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    Citation Envoyé par JerryMouse Voir le message
    Beuh! Simplicité ou complexité... c'est relatif.
    Si on me demain ce que c'est qu'une année bissextile je préfère ne pas avoir à expliquer que
    c'est une année multiple de 4 qui n'est pas multiple de 10 ou qui est multiple de 400
    surtout que c'est faux

    pas multiple de 100

  12. #12
    Membre actif Avatar de JerryMouse
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    215
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 215
    Points : 295
    Points
    295
    Par défaut
    Merci OraFrance.
    Je ne faisais qu'interpréter son code.
    J'ai jamais cherché à savoir comment ca pouvait se calculer ce truc là.
    Très souvent, le plus difficile est de savoir ce que l'on veut.

  13. #13
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut

    Bon, j'ai encore plus simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE OR REPLACE FUNCTION F_BISSEXTILE (p_annee IN NUMBER) RETURN NUMBER
    IS
    v_date DATE;
    BEGIN
     v_date := TO_DATE('29.02.'|| p_annee, 'DD.MM.RRRR');
     RETURN 1;
    EXCEPTION WHEN OTHERS THEN RETURN 0;
    END;
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  14. #14
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    plus simple certes, mais plus couteux => 1 to_date() + 1 gestion d'exception...

    Au vu des posts, je ne comprend pas vraiment pas pourquoi la solution la plus efficace (juste 3 modulos) vous rebute autant que ca...

    Une fonction de ce type peut être appelée de manière intensive...et donc être la moins couteuse...

    Ma foi...
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  15. #15
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Arf, bon, tu veux qu'on compare les durées, pas de problème je te fais un récap

    Mais bon si tu commences à calculer que 3 modulos sont plus light qu'un to_date + gestion d'erreur, je vais me permettre ceci : Une affectation est aussi couteuse, donc enlève la variable res qui ne sert à rien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE OR REPLACE FUNCTION IsBissextile(year IN number) 
     RETURN number
     IS
     begin
       IF (mod(year, 4) = 0 AND (mod(year,100) != 0 OR mod(year, 400) = 0)) then
         RETURN 1;
    END IF;
       RETURN 0;
     end;
     /
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  16. #16
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    DECLARE
    	v1 NUMBER;
      v2 NUMBER;
      r NUMBER;
      n NUMBER; b NUMBER;
    BEGIN
    	n := 0; b := 0;
    	v1 := DBMS_UTILITY.GET_TIME;
      FOR i IN -50000..50000
      LOOP
      	r := IsBissextile	(i); -- Function Modulo
    		IF r = 0 THEN n := n + 1; ELSE b := b + 1; END IF;    
      END LOOP;
      v2 := DBMS_UTILITY.GET_TIME;
      DBMS_OUTPUT.PUT_LINE(n ||' : '|| b ||' =>'||(v2-v1));
     
    n := 0; b := 0;
      v1 := DBMS_UTILITY.GET_TIME;
      FOR i IN -50000..50000
      LOOP
      	r := F_BISSEXTILE	(i); -- Function To_DATE
    		IF r = 0 THEN n := n + 1; ELSE b := b + 1; END IF;    
      END LOOP;
      v2 := DBMS_UTILITY.GET_TIME;
      DBMS_OUTPUT.PUT_LINE(n ||' : '|| b ||' =>'||(v2-v1));
    END;
    Résultats
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    75750 : 24251 =>25
    97564 : 2437 =>198
    Le modulo est plus rapide (en sachant que ce sont des 1/100ème de s), mais les résultats sont différents.
    Du fait qu'une date oracle n'est pas valide si l'année est négative ou Après je sais plus quelle année.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  17. #17
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    D'ailleurs j'ai des différences entre ta function et la mienne sur des années normales :

    diff:0<>1 : 100
    diff:0<>1 : 200
    diff:0<>1 : 300
    diff:0<>1 : 500
    diff:0<>1 : 600
    diff:0<>1 : 700
    diff:0<>1 : 900
    diff:0<>1 : 1000
    diff:0<>1 : 1100
    diff:0<>1 : 1300
    diff:0<>1 : 1400
    diff:0<>1 : 1500
    Surement un bug oracle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     SELECT TO_CHAR(TO_DATE('29.02.0100', 'DD.MM.RRRR'), 'DD/MM/RRRR')
       FROM dual
    => 29/02/0100
     
     SELECT TO_DATE('29.02.0100', 'DD.MM.RRRR')
    FROM dual
    => Erreur
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  18. #18
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    on est bien d'accord que la version modulo est de très loin plus rapide..
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  19. #19
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Oui, mais faire 100 000 calculs d'année bissextile et gagner 1.8 s ....
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  20. #20
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Citation Envoyé par McM Voir le message
    Oui, mais faire 100 000 calculs d'année bissextile et gagner 1.8 s ....
    • Utilise la fonction dans une clause where d'un requête qui tape sur des tables de gros volume...
    • La procédure peut être appelée un grand nombre de fois.....
    • 100 000 calculs c'est risible à l'échelle d'une application
    Donc , oui, gagner 1.8 secondes est important pour ce genre de fonction.

    Mois je trouve la différence importante !

    Si dans Oracle 12, to_char() était 1000% plus lent, tu serais pas vert ?

    De plus si les autres fonctions développées dans le cadre d'une appli ne sont pas elles aussi optimisée, multiplie cette différence par X fonctions et Y appels

    Au final, c'est ce genre de détails qui différencie les applis qui rament des autres

    PS : C'est la aussi la différence entr un DBA et un développeur... Le DBA n'a pas forcément en tête ce genre de considérations. Le DBA pourra être une brute Oracle, connaitre toute les optimisations et connaître 1000 fois mieux Oracle qu'un codeur mais il ne va pas forcément appliquer certaines optimisations du fait de son utilisation différente la DB. Quand un developpeur code tout un process basé sur des requêtes SQL, il a intérêt à ce que les traitement SQL soient les plus rapides possible, faire un profiling SQL afin de réduire les coût des traitement, surtout si les applis utilisent du PL/SQL
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

Discussions similaires

  1. Réponses: 3
    Dernier message: 30/08/2007, 12h58
  2. [DEBUTANT]Procédure stockée Traitement sur une boucle de requete
    Par tripper.dim dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 21/06/2007, 16h24
  3. [Dates] Tester si l'année est bissextile
    Par luluh dans le forum Langage
    Réponses: 9
    Dernier message: 11/06/2007, 15h10
  4. Comment savoir si une année est bissextile
    Par Theocourant dans le forum Contribuez
    Réponses: 3
    Dernier message: 19/09/2006, 08h10
  5. Comment savoir si une année est bisextile
    Par Theocourant dans le forum Vos contributions VB6
    Réponses: 23
    Dernier message: 03/08/2006, 10h49

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