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

AS/400 Discussion :

SQL dans RPGLE : erreur de données décimales


Sujet :

AS/400

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juillet 2009
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 38
    Points : 29
    Points
    29
    Par défaut SQL dans RPGLE : erreur de données décimales
    Bonjour
    J'ai besoin de l'aide.
    voici mon code:
    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
     
    D grn s 15 0 
    C *Entry plist 
    C parm usrname 8 
    C parm ntrf£ 9 0
    C parm whs£ 4 
    C/EXEC SQL 
    C+ DECLARE C1 CURSOR FOR 
    C+ SELECT max(t1grn£) 
    C+ FROM MABIB/MONFICH WHERE t1trf£= :ntrf£ 
    C/END-EXEC 
     
    C/EXEC SQL 
    C+ OPEN C1 
    C/END-EXEC 
     
    C if SQLSTT='00000' 
     
    C/EXEC SQL 
    C+ FETCH C1 
    C+ INTO :grn 
    C/END-EXEC 
     
    C endif
    ...................................
    L'execution m'envoie le message d'erreur suivant: ERREUR DE DONNEES DECIMALES

  2. #2
    Membre éprouvé
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Octobre 2006
    Messages
    689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Octobre 2006
    Messages : 689
    Points : 994
    Points
    994
    Par défaut
    As tu déboguer ta variable ntrf£ ?
    A tous les coups elle est mal passée.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    821
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mai 2008
    Messages : 821
    Points : 1 084
    Points
    1 084
    Par défaut
    Et puis il y a aucun intérêt à utiliser un curseur quand on ne renvoie qu'une seule ligne. Faire plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Exec SQL SELECT max(t1grn£) INTO :grn 
             FROM MABIB/MONFICH WHERE t1trf£= :ntrf£
    Le DECLARE cursor, l'OPEN et le CLOSE deviennent inutiles

  4. #4
    Membre régulier Avatar de POKOU
    Homme Profil pro
    developpeur
    Inscrit en
    Décembre 2008
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : developpeur

    Informations forums :
    Inscription : Décembre 2008
    Messages : 121
    Points : 101
    Points
    101
    Par défaut
    Bonjour
    penses à monitorer ta zone dans le FETCH avec un indicateur, pour qu'elle te renvoie 0 quand elle est à null.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    D L_ResNull1      S              2B 0
    ...
         C/EXEC SQL
         C+ FETCH NEXT FROM C1 INTO :L_IDENCONC,:L_IDBENEFI:L_RESNULL1,
         C+                         :L_DTEVTREE
         C/END-EXEC      
    ...    
    C                   IF        L_idbenefi = 0                               >2
    à+
    # Do NOT simply read the instructions in here without understanding
    # what they do. They're here only as hints or reminders. If you are unsure
    # consult the online docs. You have been warned.

  5. #5
    Membre expérimenté

    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 298
    Points : 1 578
    Points
    1 578
    Par défaut
    Quitte à définir des variables binaires, autant le faire correctement. En RPG, le " B " n'a jamais défini vraiment correctement une zone binaire car elle se limite au nombre de chiffres déclarés.

    Par exemple, si en RPG une variable est définie en "4B 0", elle ne pourra jamais contenir qu'un entier de 2 octets binaires qui ne peut contenir que 4 chiffres. Un entier binaire de 4 octets peut stocker des valeurs allant de -2147483648 à +2147483647.

    Une zone "2B 0" en RPG est certes un entier binaire de 2 octets mais ne peut stocker que des valeurs allant de -9999 à +9999.

    C'est pour cette raison que vous ne devriez plus du tout utiliser le type de donnée " B " en RPG IV. Le type de donnée correct pour une zone "BINARY(2)" est "5I 0" et le type de donnée correct pour une zone "BINARY(2) UNSIGNED" est "5U 0". Pour "BINARY(4)", déclarer alors respectivement "10I 0" et "10U 0".

    Ah ! Et +1 avec K2R400.

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Août 2008
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 123
    Points : 146
    Points
    146
    Par défaut
    Citation Envoyé par Mercure Voir le message
    Quitte à définir des variables binaires, autant le faire correctement. En RPG, le " B " n'a jamais défini vraiment correctement une zone binaire car elle se limite au nombre de chiffres déclarés.

    Par exemple, si en RPG une variable est définie en "4B 0", elle ne pourra jamais contenir qu'un entier de 2 octets binaires qui ne peut contenir que 4 chiffres. Un entier binaire de 4 octets peut stocker des valeurs allant de -2147483648 à +2147483647.

    Une zone "2B 0" en RPG est certes un entier binaire de 2 octets mais ne peut stocker que des valeurs allant de -9999 à +9999.
    Attention à ne pas confondre le nombre de chiffres (définition par la longueur des zones isolées et sous-zones) et le nombres d'octets (définition par position des sous-zones de DS). La déclaration en spec D permettant les deux (pour les sous-zones de DS), on peut facilement se perdre. Mais comme il est quand même préférable de définir les zones et sous-zones par leur longueur et non leur position, ton exemple est erronée, alors que l'explication du début est correcte ("car elle se limite au nombre de chiffres déclarés").
    Une zone en 2B 0 ne peut stocker que des valeurs allant de -99 à +99 bien que le stockage soit sur 2 octets.
    Pour les curieux, voici un petit prog rapide à faire pour tester ça.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
                                            
    D bin2            s              2B 0   
    D bin3            s              3B 0   
    D bin4            s              4B 0   
    D bin5            s              5B 0   
    D bin8            s              8B 0   
                                            
     /free                                  
         *inlr = *on;                       
         For Bin2 = 0 to 9999;            
         endfor;                            
                                
     /End-Free
    Quand le prog plantera (si, si, il va planter !) faites un dump pour voir ou la boucle s'est arrétée et la définition des différentes déclaration binaires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    NAME                  ATTRIBUTES           VALUE                        
    BIN2                  BIN(2,0)             99.              '0063'X     
    BIN3                  BIN(3,0)             000.             '0000'X     
    BIN4                  BIN(4,0)             0000.            '0000'X     
    BIN5                  BIN(5,0)             00000.           '00000000'X 
    BIN8                  BIN(8,0)             00000000.        '00000000'X
    On voit bien que Bin2 s'est limité à 99 alors qu'il est construit sur 2 octets ('0063'X).
    On remarque au passage, que le Bin(5,0) provoque le passage à 4 octets pour pouvoir stocker des valeurs supérieures à 32767 et inférieures à -32768.
    Citation Envoyé par Mercure Voir le message
    C'est pour cette raison que vous ne devriez plus du tout utiliser le type de donnée " B " en RPG IV.
    +1 ! il y a 2 ou 3 ans de cela IBM a diffusé des résultats de tests de perfs entre le binaire et l'integer : résultat, le binaire est 100 000 fois plus lent !!!
    Citation Envoyé par Mercure Voir le message
    Le type de donnée correct pour une zone "BINARY(2)" est "5I 0" et le type de donnée correct pour une zone "BINARY(2) UNSIGNED" est "5U 0". Pour "BINARY(4)", déclarer alors respectivement "10I 0" et "10U 0".
    Les définitions en I ou U contiennent un gros piège. Comme tu l'expliques, le 5U 0 est construit sur 2 octets, mais cela ne veux pas dire que l'on pourra stocker la valeur 99999 !
    Il faut se rappeler les cours de CE1 de l'informaticien : 1 octets permet de stocker 256 valeurs différentes, 2 octets permettent de stocker 65536 valeurs différentes (256*256), etc...
    Donc un 5U0 est limité aux valeurs allant de 0 à +65535. et le 5I 0 aux valeurs -32768 à +32767 ("perte" d'un bit pour le signe).
    Note : Cela fait une grosse incohérence par rapport au Binaire qui gère automatiquement le nombre d'octets utilisés en fonction de la longueur déclarée.
    Voici un extrait de la doc IBM sur les valeurs possibles pour les Integer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Field length Range of Allowed Values 
    3-digit integer -128 to 127 
    5-digit integer -32768 to 32767 
    10-digit integer -2147483648 to 2147483647 
    20-digit integer -9223372036854775808 to 9223372036854775807
    et pour les Unsigned integer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Field length Range of Allowed Values 
    3-digit unsigned 0 to 255 
    5-digit unsigned 0 to 65535 
    10-digit unsigned 0 to 4294967295 
    20-digit unsigned 0 to 18446744073709551615
    Citation Envoyé par Mercure Voir le message
    Ah ! Et +1 avec K2R400.
    +1 itou

  7. #7
    Membre expérimenté

    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 298
    Points : 1 578
    Points
    1 578
    Par défaut
    Citation Envoyé par Mercure
    Une zone "2B 0" en RPG est certes un entier binaire de 2 octets mais ne peut stocker que des valeurs allant de -9999 à +9999.
    Dans le but d'illustrer ce que je venais d'écrire au paragraphe précédent, je voulais bien entendu parler d'une zone de "4B 0" et non "2B 0". Désolé pour cette erreur bien involontaire et merci de l'avoir relevée. Je ne suis malheureusement pas à l'abri de l'erreur.

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/07/2008, 15h00
  2. [MySQL] Enregistrement d'une requête SQL dans une base de données MySQL
    Par glsn dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 15/07/2008, 13h06
  3. Problême requête SQL dans access..Erreur 3079
    Par DavidGG dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 18/01/2008, 17h48
  4. [SQL] Importer un fichier .sql dans une base de données avec PHP
    Par budiste dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 23/06/2006, 14h15
  5. [VBA]SQL dans Excel manipulation de données
    Par Deejoh dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 08/02/2006, 16h56

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