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

Cobol Discussion :

Cobol/SQL - Utilisation host variable


Sujet :

Cobol

  1. #1
    Futur Membre du Club
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Points : 7
    Points
    7
    Par défaut Cobol/SQL - Utilisation host variable
    Bonjour à tous.

    Je rencontre un souci lors d'un traitement cobol faisant des requêtes SQL de lecture via un curseur.

    Le bloc SQL à problème me permet de me repositionner dans ma lecture. Il utilise les host variables W-CLE-POS-PRIM et W-CLE-POS-SEC qui représentent mes clés de repositionnement primaire et secondaire.

    Voici mon curseur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    EXEC SQL                                                  
    DECLARE CURSEUR1 CURSOR FOR                           
        SELECT DISTINCT A.ID_1, A.ID_2,                           
        FROM Table1 A , Table2 B                            
        WHERE A.ID_2                =  B.ID_2                
          AND B.ID_2                <> :W-CTE-ID-ZERO     (vaut 00000000000000000)               
          AND B.DT_CREA BETWEEN :W-DT-CREA-1 AND :W-DT-CREA-2           
          AND B.ETAT                 = :W-ETAT                              
          AND ((A.ID_2               = :W-CLE-POS-SEC     (vaut 00000000000000000)       
            AND A.ID_1               > :W-CLE-POS-PRIM)   (vaut 00000000000000000)
            OR (A.ID_2               > :W-CLE-POS-SEC))
        ORDER BY A.ID_2,A.ID_1                     
    END-EXEC
    Mon traitement reste bloquer sur l'open du curseur à en croire les displays :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DECLARE curseur1
    SQLCODE DECLARE = 0
    OPEN curseur1
    Cependant en forçant en dur la valeur (et uniquement celle là), le traitement se débloque :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    EXEC SQL                                                  
      DECLARE CURSEUR1 CURSOR FOR                           
        SELECT DISTINCT A.ID_1, A.ID_2,                           
        FROM Table1 A , Table2 B                            
        WHERE A.ID_2                =  B.ID_2                
          AND B.ID_2                <> :W-CTE-ID-ZERO     (vaut 00000000000000000)               
          AND B.DT_CREA BETWEEN :W-DT-CREA-1 AND :W-DT-CREA-2           
          AND B.ETAT                 = :W-ETAT                              
          AND ((A.ID_2               = :W-CLE-POS-SEC     (vaut 00000000000000000)       
            AND A.ID_1               > :W-CLE-POS-PRIM)   (vaut 00000000000000000)
            OR (A.ID_2               > '00000000000000000'))
        ORDER BY A.ID_2,A.ID_1                      
    END-EXEC
    Displays :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    DECLARE curseur1
    SQLCODE DECLARE = 0
    OPEN curseur1
    SQLCODE OPEN = 0
    Environnement :
    DB2 v8
    Cobol v3.2
    Contenu de la table : > 1 000 000

    Ce que j'ai déjà tenté :
    1- essayer des valeurs en dur sur les autres champs : ne change rien
    2- utiliser des host variables différentes (au lieu de W-CLE-POS-SEC) : ne change rien
    3- Vérifier les formats des host variables W-CLE-POS-PRIM et W-CLE-POS-SEC : formats égaux à ceux de la table
    4- différentes options de pré-compil et de compil : ne change rien
    5- différentes options du BIND REOPT(VARS), REOPT(ALWAYS), REOPT(NONE) : ne change rien
    6- Utilisation d'indexes différents : ne change rien
    7- Suppression du bloc : traitement ok
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    AND ((A.ID_2               = :W-CLE-POS-SEC     (vaut 00000000000000000)       
            AND A.ID_1         > :W-CLE-POS-PRIM)   (vaut 00000000000000000)
              OR (A.ID_2       > '00000000000000000'))
    Ma question : Quelle est la différence de comportement entre une host variable et une valeur en dur ? et pourquoi sur ce champ en particulier (OR ??, et pas sur les autres) ?

    Piste : avec un contenu inférieur (test sur 20 000) : traitement OK

    Merci d'avance pour votre aide.

  2. #2
    Membre à l'essai
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Avril 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur COBOL

    Informations forums :
    Inscription : Avril 2011
    Messages : 10
    Points : 17
    Points
    17
    Par défaut
    Comment sont initialisées :W-CLE-POS-SEC et :W-CLE-POS-PRIM ?

  3. #3
    Membre chevronné Avatar de bernard59139
    Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2006
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Octobre 2006
    Messages : 950
    Points : 2 064
    Points
    2 064
    Par défaut
    Bonjour

    Si le programme "bloque" sur l'open du curseur, c'est que l'open met longtemps à faire le travail.

    je te conseillerai de demander conseil à un collègue DBA. Amha, c'est une question de runstats ou d'index.

    a+

  4. #4
    Futur Membre du Club
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Points : 7
    Points
    7
    Par défaut
    Tout d'abord, merci pour vos réponses.

    Pour tpii44119 :
    Ces variables sont initialisées à partir d'une zone de lien. J'ai contrôlé les valeurs envoyées et elles correspondent bien à des valeurs attendues (genre 00000000000000000).

    Pour bernard59139 :
    J'ai pensé aussi à un pb de runstats ou d'index mais le fait qu'avec une valeur en dur l'open fonctionne me laisse perplexe.
    J'ai aussi tenté avec d'autres indexes et de nombreux runstats/rebind mais sans succès hélàs.

  5. #5
    Membre chevronné Avatar de bernard59139
    Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2006
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Octobre 2006
    Messages : 950
    Points : 2 064
    Points
    2 064
    Par défaut
    Amha, c'est une question de runstats ou d'index.
    je ne voulais pas dire que tu n'avais pas essayer de créer les index et/ou fait (ou pas) les runstats.

    Passer certaines étapes de validation et de debug, l'aide d'un DBA te sera utile, même si ce n'est que pour faire un EXPLAIN du SQL, ou valider chacun des tests.

    COBOL n'est pour rien sur ce sujet.

  6. #6
    Futur Membre du Club
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Points : 7
    Points
    7
    Par défaut
    Les DBA sont déjà passés sur le problème (Explain, analyse minutieusement des ordres exécutés au fil du traitement)
    Il s'en est traduit une ouverture d'incident à IBM (carrément).
    Donc je tente ma chance sur le net, on ne sait jamais.

  7. #7
    Membre chevronné Avatar de bernard59139
    Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2006
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Octobre 2006
    Messages : 950
    Points : 2 064
    Points
    2 064
    Par défaut
    OK
    je te conseille de poster un message dans le forum db2 et fermer ce pst.

    Quand tu utilise une host-var, db2 estime le nombre de lignes par un calcul(voir la doc admin guide pour connaitre ce calcul).

    Quand tu utilise une valeur en "dur", db2 peut déterminer le nombre de lignes.

    Grace à ce nombre de lignes, db2 choisi le chemin d'accès le moins couteux (avec le moins de lignes).

    A savoir aussi que la zone problématique est dans un "OR". et le "OR" mal apréhendé, est tueur d'optimisation. tout comme le "not egal".

    personellement, je mettrais dans le meme ordre, les colonnes présentes dans le SELECT DISTINCT et GROUP BY. En suivant si possible l'ordre d'un index existant.

    ensuite, dans le SELECT, tu n'utilises que des colonnes de table1
    et que les critère de filtrage sont facilement lisibles sur table2 (à cause du OR)

    je tenterai une optimisation de ce genre:
    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
        SELECT DISTINCT A.ID_1, A.ID_2,                           
        FROM Table1 A  
        WHERE 
          AND (    (    A.ID_2               = :W-CLE-POS-SEC   
                    AND A.ID_1               > :W-CLE-POS-PRIM
                   ) 
            OR (A.ID_2               > '00000000000000000')
              )
    
          and exists (select '1' from          Table2 B      
                        where  A.ID_2     =  B.ID_2                
                           AND B.ID_2    <> :W-CTE-ID-ZERO  
                           AND B.DT_CREA BETWEEN :?? AND :??           
                           AND B.ETAT                 = :W-ETAT
                          )
        ORDER BY A.ID_2,A.ID_1
    Poste sur le forum db2 pour tout autre question db2.
    a+

  8. #8
    Futur Membre du Club
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Points : 7
    Points
    7
    Par défaut
    Merci Bernard.

    Ton exemple m'a insufflé une idée pour transformer ma requête.
    J'ai d'abord essayé ta proposition mais sans changement hélàs.
    L'idée vient du fait d'éclater la jointure et pour se faire j'ai utilisé un IN.
    J'ai également mis dans le même ordre le DISTINCT et l'ORDER BY.

    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
    EXEC SQL                                                  
    DECLARE CURSEUR1 CURSOR FOR                           
        SELECT DISTINCT A.ID_2, A.ID_1,                           
        FROM Table1 A                     
        WHERE ((A.ID_2               = :W-CLE-POS-SEC     (vaut 00000000000000000)       
                AND A.ID_1           > :W-CLE-POS-PRIM)   (vaut 00000000000000000)
               OR (A.ID_2            > :W-CLE-POS-SEC))    
          AND A.ID_2         IN (       
                SELECT B_ID_2 
                FROM Table 2                
                WHERE B.ID_2                <> :W-CTE-ID-ZERO     (vaut 00000000000000000)               
                AND B.DT_CREA BETWEEN :W-DT-CREA-1 AND :W-DT-CREA-2           
                AND B.ETAT                 = :W-ETAT                              
                )
        ORDER BY A.ID_2,A.ID_1                     
    END-EXEC
    Et ça marche nickel avec toutes les hosts variables

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

Discussions similaires

  1. [VBA et SQL] Requête SQL utilisant une variable VBA
    Par Altrensa dans le forum Requêtes et SQL.
    Réponses: 11
    Dernier message: 06/07/2007, 10h23
  2. [ProC][SQL] Utiliser une variable comme nom de curseur
    Par adiGuba dans le forum Interfaces de programmation
    Réponses: 1
    Dernier message: 06/12/2006, 11h55
  3. [PL/SQL] utilisation de variables dans un select?
    Par Dr Kraft dans le forum SQL
    Réponses: 8
    Dernier message: 11/10/2006, 10h17
  4. [SQL] Utilisation de variables dans une requête SQL
    Par heteroclite dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 07/09/2006, 22h38
  5. [SQL] Utilisation de variables dans une requête SQL
    Par heteroclite dans le forum Langage
    Réponses: 8
    Dernier message: 07/09/2006, 22h38

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