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 :

Curseur renvoyant deux fois la last row


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 38
    Par défaut Curseur renvoyant deux fois la last row
    Salut a tous !

    voila j'ai un soucis technique sur un curseur, il fonctionne mais à la fin il me renvoit deux fois la dernière ligne... uniquement la dernière.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SQL> select * from tb_commande;
     
    ID_PRODUIT  ID_CLIENT ID_COMMANDE DATE_COMM
    ---------- ---------- ----------- ---------
             2          2           1
             3          3           2 15-MAY-12
             2          3           4 05-MAY-01
             3         22           5 06-SEP-89
             3          3           7 18-DEC-89
     
    SQL>
    ici on a ma premiere table, et mon curseur est sensé me renvoyé les résultat dont la date est inferieur au 01/01/2012. donc il est sencé me renvoyé 3 lignes !

    voici mon curseur (avec le %notfound pourtant..)
    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
    declare
       cursor curs_alert_commande is
       select * from tb_commande
       where date_commande <= to_date('01012012','DDMMYYYY');
       dataC tb_commande%rowtype;
       begin
       open curs_alert_commande;
       loop
       fetch curs_alert_commande into dataC;
       insert into TB_ALERT(id_commande)values(dataC.id_commande);
       exit when curs_alert_commande%notfound;
       end loop;
       close curs_alert_commande;
       end;
      /
    et il me stock les résultats dans une nouvelle table. avec l'id de la commande.
    mais voici le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SQL> select * from tb_alert;
     
      ID_ALERT ID_COMMANDE
    ---------- -----------
            12           4
            13           5
            14           7
            15           7
    il m'a doublé l'id 7 ( le dernier ). J'aurais besoin d'aide pour savoir d'où cela peut-il bien venir ?!

    Merci d'avance à ce qui prendrons la peine d'intervenir.

  2. #2
    Membre chevronné
    Avatar de Bibeleuh
    Homme Profil pro
    Développeur
    Inscrit en
    Septembre 2010
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 209
    Par défaut
    Bonjour,

    Inversez l'ordre des instructions INSERT et EXIT (sinon vous insérez un enregistrement en trop car la sortie de la boucle se fait après l'insertion) :

    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
     
    DECLARE
       CURSOR curs_alert_commande
       IS
          SELECT *
            FROM tb_commande
           WHERE date_commande <= TO_DATE ('01012012', 'DDMMYYYY');
     
       dataC   tb_commande%ROWTYPE;
    BEGIN
       OPEN curs_alert_commande;
     
       LOOP
          FETCH curs_alert_commande INTO dataC;
     
          EXIT WHEN curs_alert_commande%NOTFOUND;
     
          INSERT INTO TB_ALERT (id_commande)
               VALUES (dataC.id_commande);
       END LOOP;
     
       CLOSE curs_alert_commande;
    END;
    /

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2013
    Messages : 4
    Par défaut
    Bonjour,
    Bibeleuh a raison pour les instructions mais votre code peut s'écrire plus simplement comme ceci :
    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
     
    DECLARE
       CURSOR curs_alert_commande
       IS
          SELECT *
            FROM tb_commande
           WHERE date_commande <= TO_DATE ('01012012', 'DDMMYYYY');
    BEGIN
       For mavar IN curs_alert_commande
       LOOP
           INSERT INTO TB_ALERT (id_commande)
               VALUES (mavar.id_commande);
       END LOOP;
    END;
    /
    Gros avantages : pas d'open ni de close pour le curseur, pas de fetch, pas de variable du type cursor, juste un FOR variable IN variablecursor LOOP... END LOOP
    La variable mavar est un cursor implicite, elle n'a pas besoin d'être déclarée préalablement.
    Je trouve l'écriture plus simple et plus efficace

  4. #4
    Membre expérimenté Avatar de dariyoosh
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 236
    Par défaut
    Citation Envoyé par Bruno Le Barbu Voir le message
    La variable mavar est un cursor implicite, elle n'a pas besoin d'être déclarée préalablement
    La variable mavar est un RECORD et non un cursor. Un RECORD dont les types champs sont compatiables avec les champs de chaque ligne de CURSOR lu.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2013
    Messages : 4
    Par défaut
    @dariyoosh : La variable mavar est appellée "variable implicite" ou encore "cursor implicite". C'est une appellation. Concrètement, d'un point de vue structure de données, il s'agit bien d'un record, nous sommes d'accord.
    Inutile de vouloir me reprendre sur les termes, nous parlons de la même chose.

  6. #6
    Membre expérimenté Avatar de dariyoosh
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 236
    Par défaut
    Citation Envoyé par Bruno Le Barbu Voir le message
    @dariyoosh : La variable mavar est appellée "variable implicite" ou encore "cursor implicite".
    Oui, apparemment on a une différence en termes de terminologie employée pour le même problème.
    Justement le problème c'est qu'ici on n'a pas un CURSOR implicite mais bel et bien un CURSOR explicite. En tout cas c'est comme ça qu'on a défini dans la documentation en ligne:
    http://docs.oracle.com/cd/E11882_01/...c.htm#CIHCAHJA
    An explicit cursor is a session cursor that you construct and manage. You must declare and define an explicit cursor, giving it a name and associating it with a query (typically, the query returns multiple rows). Then you can process the query result set in either of these ways:

    Open the explicit cursor (with the OPEN statement), fetch rows from the result set (with the FETCH statement), and close the explicit cursor (with the CLOSE statement).

    Use the explicit cursor in a cursor FOR LOOP statement
    Et de la même manière c'est comme ça que la documentation définit "Implicit cursor"
    http://docs.oracle.com/cd/E11882_01/...tic.htm#i46192
    An implicit cursor is a session cursor that is constructed and managed by PL/SQL. PL/SQL opens an implicit cursor every time you run a SELECT or DML statement. You cannot control an implicit cursor, but you can get information from its attributes.
    Et en plus, si je ne me trompe pas, contrairement à explicit cursor, on ne peut pas le mettre directement dans un FOR LOOP.

    Citation Envoyé par Bruno Le Barbu Voir le message
    Inutile de vouloir me reprendre sur les termes, nous parlons de la même chose.
    Ce n'était pas du tout mon objectif. C'était juste dans le cadre d'une discussion pour être clair sur le sujet comme ça se passe d'habitude sur un forum

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Citation Envoyé par Bruno Le Barbu Voir le message
    mais votre code peut s'écrire plus simplement comme ceci
    Ou même encore :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO TB_ALERT (id_commande)
    SELECT id_commande
      FROM tb_commande
     WHERE date_commande <= TO_DATE ('01012012', 'DDMMYYYY');

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

Discussions similaires

  1. [SQL] Requete me renvoyant deux fois le meme nom
    Par Pepito dans le forum Langage SQL
    Réponses: 9
    Dernier message: 14/10/2005, 14h35
  2. Lire deux fois un inputstream
    Par Guybrush dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 05/09/2005, 14h50
  3. Réponses: 14
    Dernier message: 30/03/2005, 21h50
  4. Sélectionner un même enregistrement deux fois...
    Par Manu0086 dans le forum Langage SQL
    Réponses: 11
    Dernier message: 02/02/2004, 13h09
  5. Réponses: 5
    Dernier message: 25/11/2003, 10h02

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