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 :

Traiter ligne par ligne le résultat d'une requête


Sujet :

PL/SQL Oracle

  1. #1
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Mars 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 35
    Points : 11
    Points
    11
    Par défaut Traiter ligne par ligne le résultat d'une requête
    Bonjour ,
    voici mon problème
    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
    create  OR REPLACE FUNCTION controle(cd_collab number) retrun nbe_jours is
    
    cursor cur_collab is 
    
    SELECT a.cd_collab,cd_absence,dat_deb,dat_fin
                                          INTO collab,datd,datf
                                          from absence a,demande_absence d
                                          where d.CD_DEM_ABS=a.CD_DEM_ABS
                                          and d.CD_ETAT= 4
                                          and a.CD_MOTIF in (2,3)
                                          and d.DAT_DEMANDE >='01/02/2012'
                                          order by d.cd_collab,cd_absence asc
                                
    
    var_collab  cur_collab%rowTYPE;
    var_absence cur_collab%rowTYPE;                                    
    
                                      
    BEGIN
    
    loop 
    // ici je veux selectionner la date de fin la plus grande de chaque collaborateur (exp pour le cd_collab 175 prendre la date 03/07/2012 
    
    select max(dat_fin) from cur_collab where cd_collab= var collab ;
             if max(dat_fin) = dat_deb -1 then 
    nbr_jours := dat_fin - dat_deb;
    else
    nbr_jours := dat_fin -dat_deb;
    end if ;
    
    
    return nbr_jours

  2. #2
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    C'est quoi le problème si ce n'est une syntaxe cousue de fautes et non finie ?

  3. #3
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Mars 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 35
    Points : 11
    Points
    11
    Par défaut
    oui tout a fait , et j'ai envie de savoir est ce que j'ai le droit de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select Max (dat_fin) from cur_collab where cd_collab = var_collab;
    from cur_collab , c'est toléré ?

    merci

  4. #4
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Il serait peut-être utile de revoir le fonctionnement des curseurs

    Déclaration du curseur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CURSOR C_zen IS
       SELECT a
       FROM MaTable
    Appel du curseur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    OPEN C_zen;
    FETCH C_zen INTO MaVar;
     -- mes traitements
    CLOSE C_zen
    ~ Lola ~

  5. #5
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    oui tout a fait , et j'ai envie de savoir est ce que j'ai le droit de faire :
    Select Max (dat_fin) from cur_collab where cd_collab = var_collab;
    Tu peux mais dans ce cas il faut récupérer le résultat (et non les, un SELECT ne supporte que le renvoie d'une seule ligne de données) comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT	Champs1, Champs2
    INTO	Var1, Var2
    FROM	ma_table
    WHERE	ChampsX = ma_condition;

  6. #6
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Mars 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 35
    Points : 11
    Points
    11
    Par défaut
    ok merci et si dans ma condition je veux récupérer le cd_collab sélectionné en ce moment avec mon curseur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Select Max (dat_fin) into var_date from absence where cd_collab = X.
    X= cd_collab sélectionné actuellement par le cursor

  7. #7
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Dans le lien donné plus haut il y a toute les réponses. Il faut utiliser LOOP pour faire une boucle sur les résultats du curseur. Puis le FETCH permettra de récupérer à chaque itération le résultat en cours.
    ~ Lola ~

  8. #8
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Mars 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 35
    Points : 11
    Points
    11
    Par défaut
    Je ne veux pas récupérer un résultat , mais la valeur d'un champ dans ce record

  9. #9
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Voici le lien exact pour le tutoriel des curseurs.
    ~ Lola ~

  10. #10
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Citation Envoyé par pupucette Voir le message
    je veux pas récupérer un résultat , mais la valeur d'un champs dans ce record
    Ce que j'appelle résultat sont les données renvoyées par le curseur, c'est donc bien ce que tu recherches.
    ~ Lola ~

  11. #11
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Mars 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 35
    Points : 11
    Points
    11
    Par défaut
    ok donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     Select Max (dat_fin),cd_collab 
      into var_date_fin_max ,var_collab_table
      from absence 
      where cd_collab = var_collab_table;
     
    		If var_date_fin_max = var_date_deb-1 then
    			nbr_jours := var_date_fin_max - var_date_deb;
    		Else 
    			nbr_jours := var_date_fin - var_date_deb;		  
    		End if;				   
     
    End loop;

  12. #12
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Mars 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 35
    Points : 11
    Points
    11
    Par défaut
    Par contre , il me ressort ça comme erreur :

    The following error has occurred:

    ORA-00937: La fonction de groupe ne porte pas sur un groupe simple
    ORA-06512: à "SICOM.CONTROL", ligne 35
    ORA-06512: à ligne 8

  13. #13
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Plusieurs erreurs :

    - tu ne peux pas utiliser var_collab_table dans le même SELECT

    - ton erreur est normal car il manque le group by dans ton select

    Normalement tu devrais :

    1/ déclarer ton curseur et ta variable

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    v_collab absence.cd_collab%TYPE;
     
    CURSOR C_tmp AS
      SELECT cd_collab
      FROM absence
    ;
    2/ récupérer les données de ton curseur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    OPEN C_tmp;
     
    LOOP 
     
      FETCH C_tmp INTO v_collab;
     
        SELECT max(dat_fin)
        FROM absence
        WHERE cd_collav = v_collab;
     
      EXIT WHEN C_tmp%NOTFOUND;
     
    END LOOP
    P.S : pense à mettre tes requêtes dans la balise [code]
    ~ Lola ~

  14. #14
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Je te conseille vivement quand même d'aller jeter un oeil aux cours pour que tu appréhendes mieux le concept et maîtriser ce que tu fais

    Sinon voici un exemple de curseur avec appel d'une requête SELECT :

    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
    DECLARE
     
    CURSOR C_exemple IS
    SELECT	id,dt
    FROM	ma_table
    WHERE	x=1;
     
    dt_fin  DATE;
     
    BEGIN
      FOR i IN C_exemple LOOP
        BEGIN
     
          dbms_output('Ligne ID n°'||i.id);
     
          SELECT Max(dat_fin), cd_collab
          INTO  dt_fin
          FROM  absence
          WHERE cd_collab = i.id
          GROUP BY cd_collab;
     
        EXCEPTION
          WHEN TOO_MANY_ROWS THEN
            dbms_output('Plusieurs lignes correspondent à l''ID N°'||i.id);
        END;
      END LOOP;
    END;
    /
    PS : Lors de l'utilisation d'une fonction d'aggrégat il te faut regrouper les résultats

  15. #15
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Mars 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 35
    Points : 11
    Points
    11
    Par défaut
    merci beaucoup , je vais relire le cours .
    Bonne journée à vous !

  16. #16
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Mars 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 35
    Points : 11
    Points
    11
    Par défaut
    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
    CREATE OR REPLACE FUNCTION control(cd_collab absence.cd_collab%type )return varchar IS  
    var_collab absence.cd_collab%type;
    CURSOR cur_absence IS
    
    SELECT a.cd_collab				  			 
    From absence a,demande_absence d 
    where d.CD_DEM_ABS=a.CD_DEM_ABS
    and d.CD_ETAT= 4
    and a.CD_MOTIF in (2,3)
    and d.DAT_DEMANDE >='01/02/2012'
    order by a.cd_collab;
    
    --ici je récupère les données de mon curseur 
    
    
    OPEN cur_absence;
    
    LOOP
    
    FETCH cur_absence INTO var_collab;
    
    	  select max(dat_fin)1
    	  FROM absence
    	  WHERE cd_collab = var_collab;
     	  --EXIT WHEN cur_collab%FOUND;
    
    END LOOP  
    
    If max(date_fin) = date_deb-1 then2
    			nbr_jours := max(date_fin)- date_deb;
    		Else 
    			nbr_jours := date_fin - var_date_deb;		  
    		End if;		
    close cur_absence;
    
    END;
    j'ai deux erreurs :
    1 : PLS-00428: une clause INTO est attendue dans cette instruction SELECT.
    2 : PLS-00204: fonction ou pseudo-colonne 'MAX' peut être utilisée uniquem. ds instruc. SQL

    l'équivalent de max en pl sql ?!!

  17. #17
    Membre chevronné
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Février 2012
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 652
    Points : 1 878
    Points
    1 878
    Par défaut
    Il faut que tu récupères le résultat de ton SELECT dans une variable

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [..]
    	  select max(dat_fin)
              INTO ma_variable_date
    	  FROM absence
    	  WHERE cd_collab = var_collab;
     	  --EXIT WHEN cur_collab%FOUND;
    
    END LOOP  ;
    
    If ma_variable_date = date_deb-1 then2
    [..]
    Il y a une autre erreur au niveau de ton Curseur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CURSOR cur_absence IS
    SELECT a.cd_collab				  			 
    From absence a,demande_absence d 
    where d.CD_DEM_ABS=a.CD_DEM_ABS
    and d.CD_ETAT= 4
    and a.CD_MOTIF in (2,3)
    and d.DAT_DEMANDE >='01/02/2012'
    order by a.cd_collab;
    le champs a.cd_collab ne sera pas supporté
    Il faut lui ajouter un alias

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CURSOR cur_absence IS
    SELECT a.cd_collab cd_collab
    From absence a,demande_absence d

  18. #18
    Membre émérite Avatar de lola06
    Femme Profil pro
    Consultante en Business Intelligence
    Inscrit en
    Avril 2007
    Messages
    1 316
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultante en Business Intelligence
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 316
    Points : 2 520
    Points
    2 520
    Par défaut
    Tu dois déclarer une variable qui récupéreras la valeur de ton max

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT max(...) INTO v_max FROM ...
    Puis tu utilises cette variable dans ton IF
    ~ Lola ~

  19. #19
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Mars 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 35
    Points : 11
    Points
    11
    Par défaut
    oui j'ai déja essayé , mais pas de résultat !

    la variable de la déclare comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var_D absence.cd_collab%type;

  20. #20
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Mars 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 35
    Points : 11
    Points
    11
    Par défaut
    j'ai ça comme message :

    PLS-00385: non-concordance de type détectée à 'VAR_D' dans instruction SELECT...INTO

Discussions similaires

  1. Réponses: 8
    Dernier message: 04/07/2011, 14h16
  2. Affichage par "section" des résultats d'une requête
    Par tiboleo dans le forum ASP.NET
    Réponses: 4
    Dernier message: 03/02/2010, 16h43
  3. Calcul ligne par ligne sur le résultat d'une requête
    Par CanardJM dans le forum Langage SQL
    Réponses: 5
    Dernier message: 15/04/2008, 13h06
  4. Charger une texture ligne par ligne
    Par YéTeeh dans le forum OpenGL
    Réponses: 6
    Dernier message: 09/05/2006, 09h58
  5. aditionner les champs d'une table ligne par ligne
    Par bertrand_declerck dans le forum Bases de données
    Réponses: 3
    Dernier message: 09/08/2005, 08h38

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