Précédent   Forum des professionnels en informatique > Bases de données > Oracle > PL/SQL
PL/SQL Forum d'entraide sur le PL/SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 13/12/2011, 14h04   #1
Invité de passage
 
Inscription : mars 2006
Messages : 20
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 20
Points : 1
Points : 1
Par défaut Rafraichissement d'un curseur

Bonjour,

Je cherche un moyen de rafraîchir le résultat d'un curseur ou de l'empêcher de ramener les lignes consécutives à la ligne courante du fetch. Je m'explique :

J'ai un curseur ouvert sur une vue, vue qui ramène différents résultats en doublon. J'ai une table d'exclusion qui me permet d'exclure les résultats que je ne souhaite pas voir apparaître dans le résultat de la vue. En gros, le code simplifié fait :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Declare
 
cursor C1 IS
SELECT * FROM vue1 WHERE NOT EXISTS(SELECT 1 FROM table_exclusion WHERE vue1.id = table_exclusion.id);
 
BEGIN
 
OPEN C1;
LOOP
   IF (vue1.xxxxx = 'ce que je veux') THEN
     INSERT INTO table_exclusion(id) VALUES (C1.id);
   END IF;
END LOOP;
 
END;
/
Le fait est que les données ramenés par le curseur ne prennent pas en compte les données exclues par l'insertion dans la table table_exclusion.

J'ai beau chercher, je sèche...
Je n'ai trouvé que le contournement en faisant un rownum=1 sur ma vue et en révouvrant le curseur à chaque ligne cherchée : c'est pas très optimisé...

J'ai oublié de préciser : je travaille sur Oracle 10G/HPUX11.

Si vous avez une idée, je suis preneur !

Merci d'avance.

Aurélien
AurelGTS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/12/2011, 14h51   #2
Membre Expert
 
Inscription : août 2009
Messages : 779
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 779
Points : 1 098
Points : 1 098
Non, on ne peut pas.

Par contre, vous pourriez probablement faire tout ceci en une seule requête, non ?

Et sinon, si quelque chose dans la boucle justifie le procédural, rien n'empêche de vérifier dans la boucle que la condition d'exclusion n'est pas remplie :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
Declare
 
cursor C1 IS
SELECT * FROM vue1 WHERE NOT EXISTS(SELECT 1 FROM table_exclusion WHERE vue1.id = table_exclusion.id);
 
l_check NUMBER;
 
BEGIN
 
OPEN C1;
LOOP
IF (vue1.xxxxx = 'ce que je veux') THEN
  SELECT count(id) INTO l_check FROM table_exclusion WHERE table_exclusion.id = c1.id;
  IF (CHECK =0) THEN
    INSERT INTO table_exclusion(id) VALUES (C1.id);
  END IF;
END IF;
END LOOP;
END;
Bien sûr, c'est vraiment peu performant ... encore une fois, le mieux serait de gérer ceci en une seule requête (avec du fenêtrage pour ne récupérer qu'une ligne du curseur initial et éviter les doublons).
Rei Ichido est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/12/2011, 15h33   #3
Invité de passage
 
Inscription : mars 2006
Messages : 20
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 20
Points : 1
Points : 1
Merci pour cette réponse (qui ne m'arrange pas mais merci quand même ).

Je ne peux malheureusement pas appliqué ta méthode car les requêtes que j’exécute sont dynamiques (le code que j'ai indiqué dans mon premier post était une simplification du code).

Je vais donc devoir fermer mon curseur à chaque résultat trouvé...

Cdt,

Aurélien
AurelGTS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/12/2011, 16h39   #4
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 313
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 313
Points : 5 817
Points : 5 817
Et si au lieu d’employer votre usine à gaz vous essayez d’éliminer les doublons via SQL? Et j’ai bien de doutes sur la "nécessité" de ces doublons.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 14/12/2011, 10h27   #5
Membre actif
 
Avatar de Jean_Benoit
 
Inscription : juin 2004
Messages : 495
Détails du profil
Informations personnelles :
Âge : 58

Informations forums :
Inscription : juin 2004
Messages : 495
Points : 182
Points : 182
Je ne sais pas si je comprends bien le problème.
à tout hasard voici du code pour détecter un doublon:

Code :
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
declare
 
cursor c_emp IS
   SELECT  empno,
           ename
   FROM jbmemp
   ORDER BY ename;
 
  r_emp c_emp%rowtype;
  lv_save   jbmemp.ename%type;
begin
 
  open c_emp;
  fetch c_emp INTO r_emp;
  lv_save := r_emp.ename;
  loop
     fetch c_emp INTO r_emp;
     exit when c_emp%notfound;
     IF r_emp.ename = lv_save then
        dbms_output.put_line( 'Doublon:' || r_emp.ename || ' pour empno: ' || r_emp.empno );
     end IF;
     lv_save := r_emp.ename;
     dbms_output.put_line( 'Nom: ' || r_emp.ename );
  end loop;
 
   close c_emp;
exception
   when others then
      dbms_output.put_line( 'Exc: ' || sqlerrm );
end;
J'ai un LEROND en empno 101 et un autre en empno 108.
Jean_Benoit est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/12/2011, 17h07   #6
Invité de passage
 
Inscription : mars 2006
Messages : 20
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 20
Points : 1
Points : 1
Citation:
Envoyé par mnitu Voir le message
Et si au lieu d’employer votre usine à gaz vous essayez d’éliminer les doublons via SQL? Et j’ai bien de doutes sur la "nécessité" de ces doublons.
Je pense que le fait de gérer l'exclusion par SQL est l'usine à gaz contrairement à l'utilisation d'un not exist qui évite d'ouvrir un nouveau curseur. Mais je n'ai pas le choix et vais devoir utiliser cette solution. Merci de votre aide.
AurelGTS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/12/2011, 17h10   #7
Invité de passage
 
Inscription : mars 2006
Messages : 20
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 20
Points : 1
Points : 1
Citation:
Envoyé par Jean_Benoit Voir le message
Je ne sais pas si je comprends bien le problème.
à tout hasard voici du code pour détecter un doublon:

Code :
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
declare
 
cursor c_emp IS
   SELECT  empno,
           ename
   FROM jbmemp
   ORDER BY ename;
 
  r_emp c_emp%rowtype;
  lv_save   jbmemp.ename%type;
begin
 
  open c_emp;
  fetch c_emp INTO r_emp;
  lv_save := r_emp.ename;
  loop
     fetch c_emp INTO r_emp;
     exit when c_emp%notfound;
     IF r_emp.ename = lv_save then
        dbms_output.put_line( 'Doublon:' || r_emp.ename || ' pour empno: ' || r_emp.empno );
     end IF;
     lv_save := r_emp.ename;
     dbms_output.put_line( 'Nom: ' || r_emp.ename );
  end loop;
 
   close c_emp;
exception
   when others then
      dbms_output.put_line( 'Exc: ' || sqlerrm );
end;
J'ai un LEROND en empno 101 et un autre en empno 108.
Merci mais les exclusions (pour empêcher les doublons) se trouvent dans une table. Ces valeurs sont multiples. Il faut donc que j'accède à cette table à chaque ligne rencontrée dans le vue1. Mais merci quand même.
AurelGTS est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 03h25.


 
 
 
 
Partenaires

Hébergement Web