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

SQL Oracle Discussion :

Problème de curseurs imbriqués


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2004
    Messages : 50
    Par défaut Problème de curseurs imbriqués
    Bonjour à tous, voila mon problème, je voudrais créer 2 curseurs "imbriqués" dans des boucles mais lorsque le 2nd curseur ne trouve rien dans sa requete, ca me sors pas uniquement du 2eme curseur mais aussi du 1er.

    Pour éviter ca, j'ai fais un count qui vérifie si il y a des records avant de faire la boucle mais j'aimerais savoir si il y a un moyen plus "propre" de faire ca.

    Je ne sais pas si c'est compréhensible, mais avec le code ca devrait aller mieux:

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    FUNCTION get_value_client_grp_fonds (
       client_id      IN   NUMBER,
       grp_fonds_id   IN   NUMBER,
       sdate          IN   DATE
    )
     
       RETURN NUMBER
     
    IS
     
       vtotal      BINARY_FLOAT := 0;
       vqtyfnd     BINARY_FLOAT := 0;
       vvaluefnd   BINARY_FLOAT := 0;
       vfndrate    BINARY_FLOAT := 0;
       vnbTrs      BINARY_INTEGER := 0;
     
    BEGIN
     
       FOR curgrp IN (SELECT fonds_id
                        FROM fonds_par_groupes
                       WHERE groupe_fonds_id = grp_fonds_id)
     
       LOOP
     
            /* THIS SELECT IS NOT GOOD, IT'S TO PREVENT LOOP EXIT WHEN NO TRANSACTION FOUND.
               I DON'T KNOW HOW TO DO IT PROPERLY */
     
            SELECT COUNT(1) INTO vnbTrs
                        FROM transactions
                       WHERE no_client = client_id
                         AND no_fonds = curgrp.fonds_id
                         AND date_valeur <= DECODE (sdate, NULL, SYSDATE, sdate);
     
        IF vnbTrs > 0 THEN
     
          FOR rec IN (SELECT type_transaction, quant
                        FROM transactions
                       WHERE no_client = client_id
                         AND no_fonds = curgrp.fonds_id
                         AND date_valeur <= DECODE (sdate, NULL, SYSDATE, sdate))
     
          LOOP
     
             IF rec.type_transaction = 'S' OR rec.type_transaction = 'a'
     
             THEN
     
                vqtyfnd := vqtyfnd + rec.quant;
     
             ELSIF rec.type_transaction = 'R' OR rec.type_transaction = 'r'
     
             THEN
     
                vqtyfnd := vqtyfnd - rec.quant;
     
             END IF;
     
          END LOOP;
     
          SELECT vrate
            INTO vfndrate
            FROM TABLE (get_fund_rate (curgrp.fonds_id, sdate));
     
          vvaluefnd := vqtyfnd * vfndrate;
          vtotal := vtotal + vvaluefnd;
          vfndrate := 0.0;
          vvaluefnd := 0.0;
          vqtyfnd := 0.0;
     
        END IF;
     
        vnbTrs := 0;
     
       END LOOP;
     
       RETURN vtotal;
     
    END;
    Merci

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Et pourquoi pas :
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    FUNCTION get_value_client_grp_fonds (
       client_id      IN   NUMBER,
       grp_fonds_id   IN   NUMBER,
       sdate          IN   DATE
    )
     
       RETURN NUMBER
     
    IS
     
       vtotal      BINARY_FLOAT := 0;
       vqtyfnd     BINARY_FLOAT := 0;
       vvaluefnd   BINARY_FLOAT := 0;
       vfndrate    BINARY_FLOAT := 0;
       vnbTrs      BINARY_INTEGER := 0;
     
    BEGIN
     
       FOR curgrp IN (SELECT fonds_id
                        FROM fonds_par_groupes
                       WHERE groupe_fonds_id = grp_fonds_id)
     
       LOOP
     
            /* THIS SELECT IS NOT GOOD, IT'S TO PREVENT LOOP EXIT WHEN NO TRANSACTION FOUND.
               I DON'T KNOW HOW TO DO IT PROPERLY */
     
          FOR rec IN (SELECT type_transaction, quant
                        FROM transactions
                       WHERE no_client = client_id
                         AND no_fonds = curgrp.fonds_id
                         AND date_valeur <= DECODE (sdate, NULL, SYSDATE, sdate))
     
          LOOP
     
             vnbTrs := 1;
             IF rec.type_transaction = 'S' OR rec.type_transaction = 'a'
     
             THEN
     
                vqtyfnd := vqtyfnd + rec.quant;
     
             ELSIF rec.type_transaction = 'R' OR rec.type_transaction = 'r'
     
             THEN
     
                vqtyfnd := vqtyfnd - rec.quant;
     
             END IF;
     
          END LOOP;
     
    IF vnbTrs > 0 Then
          SELECT vrate
            INTO vfndrate
            FROM TABLE (get_fund_rate (curgrp.fonds_id, sdate));
     
          vvaluefnd := vqtyfnd * vfndrate;
          vtotal := vtotal + vvaluefnd;
          vfndrate := 0.0;
          vvaluefnd := 0.0;
          vqtyfnd := 0.0;
     
        END IF;
     
        vnbTrs := 0;
     
       END LOOP;
     
       RETURN vtotal;
     
    END;
    vnbTrs à 1 dans le LOOP plutôt que compter les lignes

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2004
    Messages : 50
    Par défaut
    En fait j'aurais cru qu'il y avait peut-être une facon différente de déclarer les curseurs par exemple pour que si il ne trouve rien dans un, il ne me sorte pas complètement des 2 curseurs imbriqués. D'ailleurs est-ce que ce comportement est "normal"?

    Ou peut-être il existe une autre facon de faire.

    En tout cas merci

  4. #4
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Non ce comportament n'est pas constaté! La cause c'est l'algorithme et non pas les curseurs "imbriqués".
    Oui, il y a des autre façon à faire.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2004
    Messages : 50
    Par défaut
    Oui, il y a des autre façon à faire.
    Merci mais tu peux être un petit peu plus explicite??

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Par exemple le curseur rec est inutile, une simple requête SQL suffit à obtenir le résultat attendu, après une jointure avec le SELECT du 1er curseur et le tour est joué... à mon avis le PL/SQL n'est même pas utile pour faire ça

  7. #7
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    C'est déjà assez explicite je pense.
    Mais bon
    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
     
    For crs in (Select ...) Loop
      ...  
      For crs in (Select ...) Loop
      ...
      Begin
        Select Into From ...
        ...
      Exception
        When NO_DATA_FOUND Then
          NULL; -- Ok ça peut arrivé rien à faire
          -- ou mettez le code à faire si rien trouve
      End;
      ...
      End Loop
    End Loop;

  8. #8
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par groupe51 Voir le message
    Bonjour à tous, voila mon problème, je voudrais créer 2 curseurs "imbriqués" dans des boucles mais lorsque le 2nd curseur ne trouve rien dans sa requete, ca me sors pas uniquement du 2eme curseur mais aussi du 1er.
    ...
    Ce n'est pas vrai. C'est probablement le Select Into qui ne trouve rien et qui provoque l'exception NO_DATA_FOUND et donc la sortie.
    La solution n'est pas d'utiliser une variable suppleméntaire qui indique "j'ai trouvé ou pas" mais plutôt de prévoir le cas et le gérer correctement.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 29/03/2008, 11h36
  2. [HTML]problème de tableaux imbriqués
    Par tyrann dans le forum Balisage (X)HTML et validation W3C
    Réponses: 8
    Dernier message: 24/03/2006, 15h29
  3. Problèmes de if imbriqués
    Par hawaks dans le forum Langage
    Réponses: 6
    Dernier message: 16/12/2005, 13h17
  4. [MSDE] Problème de curseur dans une SP
    Par papouAlain dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 11/07/2005, 11h28
  5. [Trigger] Problème de curseur
    Par Superstivix dans le forum Langage SQL
    Réponses: 3
    Dernier message: 10/06/2004, 10h30

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