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

Langage SQL Discussion :

Requête de mise à jour d'un fichier


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Points : 2
    Points
    2
    Par défaut Requête de mise à jour d'un fichier
    Bonjour,
    Système : AS400
    Base de données : DB2
    Langage : Cobol
    Je dois effectuer la mise à jour d'une date située dans une zone packée et signée (DTR S9(7) COMP-3) d'un fichier physique Cobol (ZFIC0) à l'aide d'une partie d'une zone de 30 caractères alphanumériques ( de cette zone nommée LIB on extrait les 7 premiers caractères) qui se trouve dans un autre fichier (ZLIB0). Les deux fichiers ont 3 zones clés en commun et la sélection sur le deuxième fichier se fait sur la zone NUM et LIB.

    Voilà la requête que j'ai effectuée qui me donne le plus de résultats :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    UPDATE ZFIC0 AS F 
    SET F.DTR = (SELECT decimal(substr(LIBEL, 1, 7), 7, 0)
    FROM ZLIB0 AS L 
    WHERE L.CLE1 = F.CLE1 AND 
    L.CLE2 = F.CLE2 AND 
    L.CLE3 = F.CLE3 AND 
    L.NUM = 6 AND 
    DECIMAL(SUBSTR(LIBEL, 1, 7), 7, 0) > 1090930)
    J'obtiens le message suivant :
    Valeurs indéfinies non admises dans la colonne ou la variable DTR

    Auriez-vous une idée de la requête ou une autre solution pour effectuer cette mise à jour?

    Merci.

  2. #2
    rsc
    rsc est déconnecté
    Membre éprouvé
    Avatar de rsc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 711
    Points : 918
    Points
    918
    Par défaut
    Je ne connais pas DB2, ni ces messages d'erreur, mais la première possibilité qui me vienne est que pour certaines lignes, ton SELECT ne remonte rien, alors que ta colonne DTR est NOT NULL.
    Il faudrait peut-être sortir ta condition du SELECT et la rattacher à UPDATE.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    UPDATE ZFIC0 AS F
    SET F.DTR = (SELECT decimal(substr(LIBEL, 1, 7), 7, 0)
    FROM ZLIB0 AS L
    WHERE L.CLE1 = F.CLE1 AND
    L.CLE2 = F.CLE2 AND
    L.CLE3 = F.CLE3 AND
    L.NUM = 6) 
    WHERE DECIMAL(SUBSTR(LIBEL, 1, 7), 7, 0) > 1090930)
    Roland

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    J'ai déjà essayé de sortir la requête du SELECT de l'UPDATE, je l'ai testée seule et elle fonctionne, elle me donne la date que je souhaite. Cependant, je me demande si les deux formats (DTR) et la zone du SELECT à partir de laquelle se fait la mise à jour ne sont pas incompatibles.

    J'ai aussi essayé d'insérer le résultat du SELECT dans un fichier intermédiaire ZMVT0, histoire de ne pas avoir à utiliser de fonction DECIMAL et SUBSTR :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    INSERT INTO                              
    ZMVT0(mvtcle1, mvtcle2, mvtcle3, mvtdtr)                  
    SELECT L.CLE1, L.CLE2, L.CLE3, 
    DECIMAL(SUBSTR(L.LIB, 1, 7), 7, 0)                       
    FROM ZLIB0 AS L, ZFIC0 AS M
    WHERE L.CLE1 = M.CLE1 AND           
          L.CLE2 = M.CLE2 AND           
          L.CLE3 = M.CLE3 AND           
          L.NUM = 6 AND                   
          DECIMAL(SUBSTR(L.LIB, 1, 7), 7, 0) > 1090930

    J'arrive à insérer dans le fichier intermédiaire mais la jointure UPDATE ne fonctionne toujours pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    UPDATE ZFIC0 AS F
    SET F.DTR = (SELECT MVTDTR
    FROM ZMVT0 AS L
    WHERE L.CLE1 = F.CLE1 AND
    L.CLE2 = F.CLE2 AND
    L.CLE3 = F.CLE3)
    Merci pour vos réponses.

  4. #4
    rsc
    rsc est déconnecté
    Membre éprouvé
    Avatar de rsc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 711
    Points : 918
    Points
    918
    Par défaut
    Il est possible qu'il y ait un problème de format, je ne suis pas apte à juger. Sinon, ta table intermédiaire peut servir à vérifier mon hypothèse : Y a-t-il dans ZMVTO des lignes où MVTDTR est NULL ? Ne seraient-ce pas ces lignes qui posent problème ? (essaie de les supprimer avant de faire l'UPDATE).
    Roland

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Il n'y a aucune zone où MVTDTR est NULL, en fait je n'ai qu'une seule ligne dans le SELECT, elle contient une date numérique de 7 caractères, qui correspond avec le format de la zone cible.

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    J'ai aussi essayé d'ajouté la fonction TRIM au résultat du SELECT, idem pour le message d'erreur, valeurs indéfinies.

  7. #7
    rsc
    rsc est déconnecté
    Membre éprouvé
    Avatar de rsc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 711
    Points : 918
    Points
    918
    Par défaut
    Je m'explique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DECIMAL(SUBSTR(L.LIB, 1, 7), 7, 0) > 1090930
    est une condition.
    Soit elle est toujours remplie, auquel cas elle est inutile ,
    soit elle n'est pas toujours remplie, auquel cas, ton SELECT ne te renvoie aucune ligne, ce qui revient à faire (pour cette ligne-là) . D'où ma question.
    Roland

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par rsc Voir le message
    Je m'explique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DECIMAL(SUBSTR(L.LIB, 1, 7), 7, 0) > 1090930
    est une condition.
    Soit elle est toujours remplie, auquel cas elle est inutile ,
    soit elle n'est pas toujours remplie, auquel cas, ton SELECT ne te renvoie aucune ligne, ce qui revient à faire (pour cette ligne-là) . D'où ma question.
    Pour contourner le problème que vous posez, j'ai le même problème avec cette condition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUBSTR(L.LIB, 1, 7) = '1090930'
    Cela vous parle-t-il plus?

    Merci.

  9. #9
    rsc
    rsc est déconnecté
    Membre éprouvé
    Avatar de rsc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 711
    Points : 918
    Points
    918
    Par défaut
    C'est certain, si mon hypothèse est juste, tu auras le pb avec toutes les conditions sauf celles qui sont toujours remplies

    Pour tester mon hypothèse, le plus simple est peut-être de faire tout simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE ZFIC0 AS F 
    SET F.DTR = NULL
    soit sur toute la table si elle ne contient pas de données, soit en sélectionnant une seule ligne avec une clause WHERE.
    Roland

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par rsc Voir le message
    C'est certain, si mon hypothèse est juste, tu auras le pb avec toutes les conditions sauf celles qui sont toujours remplies

    Pour tester mon hypothèse, le plus simple est peut-être de faire tout simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE ZFIC0 AS F 
    SET F.DTR = NULL
    soit sur toute la table si elle ne contient pas de données, soit en sélectionnant une seule ligne avec une clause WHERE.
    Après avoir testé votre requête exacte, le message renvoyé est toujours le même : valeurs indéfinies...Le système ne le permet peut-être tout simplement pas, dans ce cas il me faudra trouver une autre solution

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    J'ai aussi essayé cette requête qui me dit que le mot JOIN est mal placé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    UPDATE ZFIC0 AS F                        
    SET F.DTR = 1091001                
    JOIN ZLIB0 AS L                           
    ON (L.CLE1 = F.CLE1               
    AND L.CLE2 = F.CLE2
    AND L.CLE3 = F.CLE3
    AND L.NUM = 6                       
    AND SUBSTR(L.LIB, 1, 7) = '1091001')
    Cette requête-ci fonctionne mais ne répond pas à mon problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    UPDATE ZFIC0 AS F                                     
    SET F.DTR = 1091003                                        
    WHERE F.CLE1 IN 
    (SELECT L.CLE1 
    FROM ZLIB0 
    WHERE L.CLE1 =F.CLE1 
    AND L.CLE2 =F.CLE2  
    AND L.CLE3 =F.CLE3 
    AND L.NUM = 6 
    AND SUBSTR(L.LIB, 1, 7) = '1091001')
    Une autre solution serait de créer un CL qui ferait cette dernière requête pour chaque date possible dans le ZLIB0. Mais c'est un peu fastidieux...

  12. #12
    rsc
    rsc est déconnecté
    Membre éprouvé
    Avatar de rsc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 711
    Points : 918
    Points
    918
    Par défaut
    Non ça n'est pas impossible ! Il "suffit" de filtrer les lignes à mettre à jour en s'assurant qu'elles correspondent à des valeurs non nulles. Cela devrait donner qqch comme :
    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
    UPDATE ZFIC0 AS F
    SET F.DTR = 
    /* La valeur à insérer */
    (SELECT decimal(substr(L.LIB, 1, 7), 7, 0)
    FROM ZLIB0 AS L
    WHERE L.CLE1 = F.CLE1 AND
    L.CLE2 = F.CLE2 AND
    L.CLE3 = F.CLE3 AND
    L.NUM = 6
    /* Cette ligne doit être superflue, à tester */
    AND DECIMAL(SUBSTR(L2.LIB, 1, 7), 7, 0) > 1090930)) 
    /* la condition qui vérifie que cette valeur n'est pas nulle */
    WHERE EXISTS (SELECT decimal(substr(L2.LIB, 1, 7), 7, 0)
    FROM ZLIB0 AS L2
    WHERE L2.CLE1 = F.CLE1 AND
    L2.CLE2 = F.CLE2 AND
    L2.CLE3 = F.CLE3 AND
    L2.NUM = 6
    AND DECIMAL(SUBSTR(L2.LIB, 1, 7), 7, 0) > 1090930))
    Je ne sais pas s'il 'y a moyen de simplifier. Sans doute, mais je ne vois pas...
    Roland

  13. #13
    rsc
    rsc est déconnecté
    Membre éprouvé
    Avatar de rsc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 711
    Points : 918
    Points
    918
    Par défaut
    Citation Envoyé par Jerome56 Voir le message
    J'ai aussi essayé cette requête qui me dit que le mot JOIN est mal placé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    UPDATE ZFIC0 AS F                        
    SET F.DTR = 1091001                
    JOIN ZLIB0 AS L                           
    ON (L.CLE1 = F.CLE1               
    AND L.CLE2 = F.CLE2
    AND L.CLE3 = F.CLE3
    AND L.NUM = 6                       
    AND SUBSTR(L.LIB, 1, 7) = '1091001')
    Logique, on ne peut pas faire de jointure dans un UPDATE.
    Roland

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    861
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 861
    Points : 965
    Points
    965
    Par défaut
    Logique, on ne peut pas faire de jointure dans un UPDATE.
    Vous parlez de SQL ou de DB2 en particulier?
    Ceci est possible en SQL, mais je ne connais pas DB2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    UPDATE T1
    JOIN T2 ON T1.id = t2.id
    SET T1.col1 = T2.col1;

  15. #15
    rsc
    rsc est déconnecté
    Membre éprouvé
    Avatar de rsc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2004
    Messages
    711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 711
    Points : 918
    Points
    918
    Par défaut
    Citation Envoyé par Snipah Voir le message
    Vous parlez de SQL ou de DB2 en particulier?
    Ceci est possible en SQL, mais je ne connais pas DB2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    UPDATE T1
    JOIN T2 ON T1.id = t2.id
    SET T1.col1 = T2.col1;
    Je ne suis pas sûr que ça fasse partie de la norme SQL, même si cela me semblerait logique et extrêmement utile. Ca ne marche en tous cas ni sous Oracle, ni sous Firebird.
    Roland

  16. #16
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 814
    Points
    17 814
    Par défaut
    Concernant Oracle, il y a MERGE qui est relativement puissant et qui permet les mises à jour d'une table à partir d'une vue.

    On peut aussi faire des updates de vues (avec une autre syntaxe) mais uniquement sous certaines conditions.

  17. #17
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Je reviens vers vous pour vous dire que j'ai trouvé une réponse à notre problème (qui n'est pas encore tout à fait conforme à la solution que j'attends, mais c'est déjà ça!) :

    Voici le code qui met correctement à jour la ligne du ZFIC0 que je veux avec la bonne valeur du ZLIB0 :

    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
     
    UPDATE ZFIC0 AS F                                   
    SET F.DTR = (SELECT DECIMAL(SUBSTR(L.LIB, 1, 7), 7, 0)
                     FROM ZLIB0 AS L                    
                     WHERE L.CLE1 = F.CLE1 AND              
                           L.CLE2 = F.CLE2 AND              
                           L.CLE3 = F.CLE3 AND              
                           L.NUM = 6)   
    WHERE F.CLE1 IN (                                         
    SELECT L.CLE1 FROM  ZLIB0  AS L                   
    WHERE L.CLE1 = F.CLE1 AND              
                           L.CLE2 = F.CLE2 AND              
                           L.CLE3 = F.CLE3 AND              
                           L.NUM = 6 AND                      
                           SUBSTR(L.LIB, 1, 7) > '1090930')
    Merci pour vos indications rsc, elles m'ont aidé à voir que sans la deuxième clause WHERE, on voulait mettre à jour toutes les lignes du ZFIC0, or je ne voulais mettre à jour que certaines lignes (celles dont la clé du ZLIB0 et du ZFIC0 coïncident, avec une sélection sur le numéro 6 du ZLIB0 et la date)

    Je vous expose plus avant mon problème, qui n'en est plus un :

    Dans le cadre d'une reprise de données d'un système source A vers un système cible B, on utilise un module qui met à jour la date de traitement du ZFIC0 F.DTR dans le système cible B à la date du jour. Or il faut que cette date de traitement soit celle de l'ancien système A. On remonte donc l'ancienne date dans la zone L.LIB du ZLIB0 et on lance la requête d'UPDATE précédente pour remettre les dates sources dans le système cible.

    Je considère cette discussion comme résolue.

    A vos avis!

    Merci à tous!

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

Discussions similaires

  1. Requête de mise à jour
    Par Deejoh dans le forum Access
    Réponses: 4
    Dernier message: 24/05/2006, 13h02
  2. Réponses: 2
    Dernier message: 10/03/2006, 14h55
  3. Réponses: 3
    Dernier message: 05/12/2005, 15h17
  4. Réponses: 6
    Dernier message: 29/11/2005, 20h36
  5. [Système] mise à jour d'un fichier .htpasswd
    Par ikkyu_os dans le forum Langage
    Réponses: 4
    Dernier message: 15/09/2005, 11h25

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