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 :

Problème CASE SQL ORACLE


Sujet :

PL/SQL Oracle

  1. #1
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2019
    Messages : 72
    Par défaut Problème CASE SQL ORACLE
    Bonjour,

    Voici ma requête :
    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
    DECLARE CURSOR c IS select * from haplo where notest IN('KCAS', 'MBCAS', 'SHGC', 'MTP', 'MSHGC') and nunati='2521224874';
    BEGIN
      DECLARE resultest varchar2(1000) := '';
      BEGIN
        FOR r in c 
        LOOP 
          CASE WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc' AND r.TYPTEST= 'H' AND r.RESULTEST = '0') THEN
            RESULTEST := 'NP';
          WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc' AND r.TYPTEST= 'H' AND r.RESULTEST = '1') THEN
            RESULTEST := 'SH';
          WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc' AND r.TYPTEST= 'H' AND r.RESULTEST = 'IN') THEN
            RESULTEST := 'IN';
          END CASE;
          SELECT CONCAT(resultest, r.notest || ':' || r.resultest || ';') INTO resultest FROM dual;
        END LOOP;
      dbms_output.put_line(resultest);
      END;
    END;
    Mon message d'erreur est :
    Rapport d'erreur -
    ORA-06592: CASE introuvable lors de l'exécution de l'instruction CASE
    ORA-06512: à ligne 7
    06592. 00000 - "CASE not found while executing CASE statement"
    *Cause: A CASE statement must either list all possible cases or have an
    else clause.
    *Action: Add all missing cases or an else clause.
    Je ne trouve pas le problème dans mon case, peut être une erreur de syntaxe ?
    J'utilise une base de données Oracle.

    Merci d'avance.

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 544
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 544
    Billets dans le blog
    10
    Par défaut
    Bonsoir,
    Le point virgule est une fin d'instruction, du coup les WHEN suivants ne sont pas compris comme partie intégrante du CASE.

    Attention aussi aux combinaisons de AND / OR sans parenthèses

  3. #3
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 167
    Par défaut
    Bonjour,

    Pourquoi faire ce test en pl/sql? Au maximum il faut privilégier le sql. Tu peux simplement faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT CASE WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc' AND r.TYPTEST= 'H' AND r.RESULTEST = '0') 
                THEN decode(r.RESULTEST, 0, 'NP', '1', 'SH', 'IN', 'IN')            
            END   
            || r.notest || ':' || r.resultest || ';'
    FROM haplo r
    WHERE notest IN ('KCAS', 'MBCAS', 'SHGC', 'MTP', 'MSHGC')
      AND nunati='2521224874';
    A noter que la condition "OR r.NOTEST = 'shgc'" est inutile vu que cette valeur n'est pas sélectionnée dans la clause WHERE (elle l'est en majuscules). De plus, ne manque-t-il pas un ELSE pour l'instruction CASE?

  4. #4
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Bonjour, comme dans le port-salut c'est écrit
    ...
    *Cause: A CASE statement must either list all possible cases or have an
    else clause.
    ...
    Donc il faut un ELSE en PLSQL (contrairement au CASE en SQL)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CASE WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc' AND r.TYPTEST= 'H' AND r.RESULTEST = '0') THEN
            RESULTEST := 'NP';
          WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc' AND r.TYPTEST= 'H' AND r.RESULTEST = '1') THEN
            RESULTEST := 'SH';
          WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc' AND r.TYPTEST= 'H' AND r.RESULTEST = 'IN') THEN
            RESULTEST := 'IN';
    ELSE NULL;
          END CASE;

  5. #5
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2019
    Messages : 72
    Par défaut
    Du coup maintenant ça marche :

    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
    DECLARE CURSOR c IS select * from haplo where notest IN('KCAS', 'MBCAS', 'SHGC', 'MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP', 'MSHGC') and nunati = '0114035148'
    order by (case notest when 'KCAS' then 0 
                          when 'SHGC' then 1
                          when 'MSHGC' then 2
                          when 'MMTCP' then 3
                          when 'MMTP' then 4
                          when 'MMH3' then 5
                          when 'HMTP' then 6
                          when 'HMH3' then 7
                          when 'HMTCP' then 8
                          when 'MBCAS' then 9 
                          end); 
    BEGIN
      DECLARE 
      varRESULTEST varchar2(1000) := NULL;
      varNOTEST varchar2(1000) := NULL;
      chainefinale varchar2(1000) := NULL;
      BEGIN
        FOR r in c 
        LOOP   
                           --Affectation des valeurs pour regrouper les tests.
            varNOTEST := CASE WHEN r.NOTEST = 'KCAS' THEN 'KCAS'
                              WHEN r.NOTEST = 'MBCAS' THEN 'MBCAS'
                              WHEN r.NOTEST IN ('MSHGC', 'SHGC') THEN 'SHGC'
                              WHEN r.NOTEST IN ('MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP') THEN 'MTP'
                         END;
                                 --Cas 'SHGC' 
            varRESULTEST := CASE WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = '0' THEN 'NP'
                                 WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = '1' THEN 'SH'
                                 WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = 'IN' THEN 'IN'
     
                                  --Cas 'MTP'
                                  WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTF' THEN 'NP' 
                                  WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTC' THEN 'Porteur'
     
                                  WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPF' THEN 'NP'
                                  WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPC' OR r.RESULTEST='MTP' THEN 'NP'
     
                                  WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3F' THEN 'NP'
                                  WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3C' OR r.RESULTEST='MH3S' THEN 'NP'
     
                                  WHEN r.NOTEST='HMTCP' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMTCP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                                  WHEN r.NOTEST='HMTP' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMTP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                                  WHEN r.NOTEST='HMH3' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMH3' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                            END;
     
            SELECT CASE WHEN varRESULTEST IS NOT NULL THEN varNOTEST || ':' || varRESULTEST || ';'
                        WHEN varRESULTEST IS NULL THEN varNOTEST || ':' || r.RESULTEST || ';'
                   END
            INTO varRESULTEST
            FROM DUAL;
            SELECT CONCAT(chainefinale, varRESULTEST) INTO chainefinale FROM DUAL;
        END LOOP;
        dbms_output.put_line(chainefinale);
      END;
    END;
    Le seul soucis est qu'au lieu de m'afficher une seule fois MTP : Resultat il m'affiche : KCAS:AB;SHGC:SHF;MTP:NP;MTP:NP;MTP:NP;MBCAS:A1A2;
    Or j'aimerai qu'il s'affiche une seule fois. Pour le Cas MTP, dès qu'il trouve un résultat par exemple grâce a R.NOTEST = 'MMTCP' je souhaiterai que le case se stop et mette le résultat attendu. Si la condition pour R.NOTEST = 'MMTCP' n'est pas trouvé alors on passe au cas r.NOTEST='MMTP' et ainsi de suite.

  6. #6
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Sans cas concret c'est compliqué de comprendre ce qui ne va pas avec le résultat.

    Toutefois :
    1/ Attention aux conditions combinées AND et OR (le AND est prioritaire), mais il vaut mieux mettre des () pour rendre le code plus lisible
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPC' OR r.RESULTEST='MTP' THEN 'NP'
    Test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT 1 as a
    FROM dual
    WHERE 1=0 AND 1=1 OR 1=1
     
    a
    1
    2/ Pourquoi faire un SELECT FROM DUAL (donc du SQL) pour des simples tests, c'est moins performant que de faire un IF (PLSQL), de plus le second WHEN peut être remplacé par ELSE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT CASE WHEN varRESULTEST IS NOT NULL THEN varNOTEST || ':' || varRESULTEST || ';'
                        WHEN varRESULTEST IS NULL THEN varNOTEST || ':' || r.RESULTEST || ';'
                   END
            INTO varRESULTEST
            FROM DUAL;
    =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    IF  varRESULTEST IS NOT NULL 
    THEN varRESULTEST := varNOTEST || ':' || varRESULTEST || ';';
    ELSE varRESULTEST := varNOTEST || ':' || r.RESULTEST || ';';
    END IF;
    3/ pareil pour le Concat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT CONCAT(chainefinale, varRESULTEST) INTO chainefinale FROM DUAL;
    =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chainefinale  := chainefinale  || varRESULTEST;

  7. #7
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2019
    Messages : 72
    Par défaut
    Pour le cas MTP :
    Mon case when doit s'arreter au moment ou il trouve un resultat, or il ne s'arrete pas

  8. #8
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Le CASE s'arrête toujours quand il trouve quelque chose.
    Tu interprètes mal le résultat.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    DECLARE
    	v NUMBER;
    BEGIN
    	v := CASE WHEN 1 = 1 THEN 1
      			WHEN 1 = 1 THEN 2
            WHEN 1 = 1 THEN 3
            ELSE 0 END;
      DBMS_OUTPUT.put_line(v);
    END;
     
     
    1
    Vu que tu es dans une boucle sur un SELECT, c'est sûrement ça qui te pose problème. Le SELECT te ramène 2 lignes

  9. #9
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2019
    Messages : 72
    Par défaut
    Je n'arrive pas a mettre a jour mon code avec ton explication :
    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
    DECLARE CURSOR c IS select * from haplo where notest IN('KCAS', 'MBCAS', 'SHGC', 'MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP', 'MSHGC') and nunati = '0114035148'
    order by (case notest when 'KCAS' then 0 
                          when 'SHGC' then 1
                          when 'MSHGC' then 2
                          when 'MMTCP' then 3
                          when 'MMTP' then 4
                          when 'MMH3' then 5
                          when 'HMTP' then 6
                          when 'HMH3' then 7
                          when 'HMTCP' then 8
                          when 'MBCAS' then 9 
                          end); 
    BEGIN
      DECLARE 
      varRESULTEST varchar2(1000) := NULL;
      varNOTEST varchar2(1000) := NULL;
      chainefinale varchar2(1000) := NULL;
      BEGIN
        FOR r in c 
        LOOP   
                           --Affectation des valeurs pour regrouper les tests.
            varNOTEST := CASE WHEN r.NOTEST = 'KCAS' THEN 'KCAS'
                              WHEN r.NOTEST = 'MBCAS' THEN 'MBCAS'
                              WHEN r.NOTEST IN ('MSHGC', 'SHGC') THEN 'SHGC'
                              WHEN r.NOTEST IN ('MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP') THEN 'MTP'
                         END;
                                 --Cas 'SHGC' 
            varRESULTEST := CASE WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = '0' THEN 'NP'
                                 WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = '1' THEN 'SH'
                                 WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = 'IN' THEN 'IN'
     
                                  --Cas 'MTP'
                                  WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTF' THEN 'NP' 
                                  WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTC' THEN 'Porteur'
     
                                  WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPF' THEN 'NP'
                                  WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPC' OR r.RESULTEST='MTP' THEN 'NP'
     
                                  WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3F' THEN 'NP'
                                  WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3C' OR r.RESULTEST='MH3S' THEN 'NP'
     
                                  WHEN r.NOTEST='HMTCP' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMTCP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                                  WHEN r.NOTEST='HMTP' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMTP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                                  WHEN r.NOTEST='HMH3' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMH3' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                            END;
     
            SELECT CASE WHEN varRESULTEST IS NOT NULL THEN varNOTEST || ':' || varRESULTEST || ';'
                        WHEN varRESULTEST IS NULL THEN varNOTEST || ':' || r.RESULTEST || ';'
                   END
            INTO varRESULTEST
            FROM DUAL;
            SELECT CONCAT(chainefinale, varRESULTEST) INTO chainefinale FROM DUAL;
        END LOOP;
        dbms_output.put_line(chainefinale);
      END;
    END;
    Je souhaite juste que pour ce cas :
    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
     --Cas 'MTP'
                                  WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTF' THEN 'NP' 
                                  WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTC' THEN 'Porteur'
     
                                  WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPF' THEN 'NP'
                                  WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPC' OR r.RESULTEST='MTP' THEN 'NP'
     
                                  WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3F' THEN 'NP'
                                  WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3C' OR r.RESULTEST='MH3S' THEN 'NP'
     
                                  WHEN r.NOTEST='HMTCP' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMTCP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                                  WHEN r.NOTEST='HMTP' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMTP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                                  WHEN r.NOTEST='HMH3' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMH3' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
    Il s'arrete des qu'il trouve un resultat.
    Comme ça au lieu d'obtenir en résultat : KCAS:AB;SHGC:SHF;MTP:NP;MTP:NP;MTP:NP;MBCAS:A1A2;
    J'obtiendrais : KCAS:AB;SHGC:SHF;MTP:NP;MBCAS:A1A2;

  10. #10
    Membre Expert
    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
    Par défaut
    Le problème principal, c'est que nous n'avons pas de boule de cristal permettant de savoir ce qu'il ressort du curseur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    select * from haplo where notest IN('KCAS', 'MBCAS', 'SHGC', 'MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP', 'MSHGC') and nunati = '0114035148'
    order by (case notest when 'KCAS' then 0 
                          when 'SHGC' then 1
                          when 'MSHGC' then 2
                          when 'MMTCP' then 3
                          when 'MMTP' then 4
                          when 'MMH3' then 5
                          when 'HMTP' then 6
                          when 'HMH3' then 7
                          when 'HMTCP' then 8
                          when 'MBCAS' then 9 
                          end);
    Et c'est très certainement cette requête qui sort deux fois la valeur 'MTP', donc l'erreur ne se situerait-elle pas à ce niveau ?
    Ou alors il s'agit de ne traiter qu'une seul fois la valeur 'MTP' même si le curseur ramène plusieurs fois cette valeur ?

    D'autre part, pour le tri il est possible d'alléger la syntaxe via un DECODE (A voir selon votre préférence) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select * 
    from haplo 
    where notest IN('KCAS', 'MBCAS', 'SHGC', 'MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP', 'MSHGC') 
    and nunati = '0114035148'
    order by DECODE(notest, 'KCAS', 0,'SHGC', 1,'MSHGC', 2,'MMTCP', 3,'MMTP', 4,'MMH3', 5,'HMTP', 6,'HMH3', 7,'HMTCP', 8,'MBCAS', 9, 99)
    Pour le reste du code, si l'on prend les préconisations de McM de remplacer les instructions SQL (inutiles) et que l'on passe directement par du PL/SQL, on obtient 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
    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
    DECLARE CURSOR c IS 
      select * 
      from haplo 
      where notest IN('KCAS', 'MBCAS', 'SHGC', 'MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP', 'MSHGC') 
      and nunati = '0114035148'
      order by DECODE(notest 'KCAS', 0,'SHGC', 1,'MSHGC', 2,'MMTCP', 3,'MMTP', 4,'MMH3', 5,'HMTP', 6,'HMH3', 7,'HMTCP', 8,'MBCAS', 9, 99);
     
    BEGIN
      DECLARE 
      varRESULTEST varchar2(1000) := NULL;
      varNOTEST varchar2(1000) := NULL;
      chainefinale varchar2(1000) := NULL;
      BEGIN
        FOR r in c 
        LOOP   
                           --Affectation des valeurs pour regrouper les tests.
            varNOTEST := CASE WHEN r.NOTEST = 'KCAS' THEN 'KCAS'
                              WHEN r.NOTEST = 'MBCAS' THEN 'MBCAS'
                              WHEN r.NOTEST IN ('MSHGC', 'SHGC') THEN 'SHGC'
                              WHEN r.NOTEST IN ('MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP') THEN 'MTP'
                         END;
                                 --Cas 'SHGC' 
            varRESULTEST := CASE WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = '0' THEN 'NP'
                                 WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = '1' THEN 'SH'
                                 WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = 'IN' THEN 'IN'
     
                                  --Cas 'MTP'
                                  WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTF' THEN 'NP' 
                                  WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTC' THEN 'Porteur'
     
                                  WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPF' THEN 'NP'
                                  WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPC' OR r.RESULTEST='MTP' THEN 'NP'
     
                                  WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3F' THEN 'NP'
                                  WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3C' OR r.RESULTEST='MH3S' THEN 'NP'
     
                                  WHEN r.NOTEST='HMTCP' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMTCP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                                  WHEN r.NOTEST='HMTP' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMTP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                                  WHEN r.NOTEST='HMH3' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMH3' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                            END;
     
            IF  varRESULTEST IS NOT NULL 
              THEN varRESULTEST := varNOTEST || ':' || varRESULTEST || ';';
              ELSE varRESULTEST := varNOTEST || ':' || r.RESULTEST || ';';
            END IF;
            chainefinale  := chainefinale  || varRESULTEST;
        END LOOP;
        dbms_output.put_line(chainefinale);
      END;
    END;

  11. #11
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 167
    Par défaut
    Sur le principe, comme je le disais dans ma précédente réponse, il est inutile de faire du pl/sql pour ce genre de test, mettre tout dans la requête du curseur suffit, même pas besoin de pl/sql.

  12. #12
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2019
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2019
    Messages : 72
    Par défaut
    Citation Envoyé par Scriuiw Voir le message
    Le problème principal, c'est que nous n'avons pas de boule de cristal permettant de savoir ce qu'il ressort du curseur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    select * from haplo where notest IN('KCAS', 'MBCAS', 'SHGC', 'MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP', 'MSHGC') and nunati = '0114035148'
    order by (case notest when 'KCAS' then 0 
                          when 'SHGC' then 1
                          when 'MSHGC' then 2
                          when 'MMTCP' then 3
                          when 'MMTP' then 4
                          when 'MMH3' then 5
                          when 'HMTP' then 6
                          when 'HMH3' then 7
                          when 'HMTCP' then 8
                          when 'MBCAS' then 9 
                          end);
    Et c'est très certainement cette requête qui sort deux fois la valeur 'MTP', donc l'erreur ne se situerait-elle pas à ce niveau ?
    Ou alors il s'agit de ne traiter qu'une seul fois la valeur 'MTP' même si le curseur ramène plusieurs fois cette valeur ?

    D'autre part, pour le tri il est possible d'alléger la syntaxe via un DECODE (A voir selon votre préférence) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select * 
    from haplo 
    where notest IN('KCAS', 'MBCAS', 'SHGC', 'MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP', 'MSHGC') 
    and nunati = '0114035148'
    order by DECODE(notest, 'KCAS', 0,'SHGC', 1,'MSHGC', 2,'MMTCP', 3,'MMTP', 4,'MMH3', 5,'HMTP', 6,'HMH3', 7,'HMTCP', 8,'MBCAS', 9, 99)
    Pour le reste du code, si l'on prend les préconisations de McM de remplacer les instructions SQL (inutiles) et que l'on passe directement par du PL/SQL, on obtient 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
    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
    DECLARE CURSOR c IS 
      select * 
      from haplo 
      where notest IN('KCAS', 'MBCAS', 'SHGC', 'MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP', 'MSHGC') 
      and nunati = '0114035148'
      order by DECODE(notest 'KCAS', 0,'SHGC', 1,'MSHGC', 2,'MMTCP', 3,'MMTP', 4,'MMH3', 5,'HMTP', 6,'HMH3', 7,'HMTCP', 8,'MBCAS', 9, 99);
     
    BEGIN
      DECLARE 
      varRESULTEST varchar2(1000) := NULL;
      varNOTEST varchar2(1000) := NULL;
      chainefinale varchar2(1000) := NULL;
      BEGIN
        FOR r in c 
        LOOP   
                           --Affectation des valeurs pour regrouper les tests.
            varNOTEST := CASE WHEN r.NOTEST = 'KCAS' THEN 'KCAS'
                              WHEN r.NOTEST = 'MBCAS' THEN 'MBCAS'
                              WHEN r.NOTEST IN ('MSHGC', 'SHGC') THEN 'SHGC'
                              WHEN r.NOTEST IN ('MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP') THEN 'MTP'
                         END;
                                 --Cas 'SHGC' 
            varRESULTEST := CASE WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = '0' THEN 'NP'
                                 WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = '1' THEN 'SH'
                                 WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H' AND r.RESULTEST = 'IN' THEN 'IN'
     
                                  --Cas 'MTP'
                                  WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTF' THEN 'NP' 
                                  WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTC' THEN 'Porteur'
     
                                  WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPF' THEN 'NP'
                                  WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPC' OR r.RESULTEST='MTP' THEN 'NP'
     
                                  WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3F' THEN 'NP'
                                  WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3C' OR r.RESULTEST='MH3S' THEN 'NP'
     
                                  WHEN r.NOTEST='HMTCP' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMTCP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                                  WHEN r.NOTEST='HMTP' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMTP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                                  WHEN r.NOTEST='HMH3' AND r.RESULTEST='0' THEN 'NP'
                                  WHEN r.NOTEST='HMH3' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                            END;
     
            IF  varRESULTEST IS NOT NULL 
              THEN varRESULTEST := varNOTEST || ':' || varRESULTEST || ';';
              ELSE varRESULTEST := varNOTEST || ':' || r.RESULTEST || ';';
            END IF;
            chainefinale  := chainefinale  || varRESULTEST;
        END LOOP;
        dbms_output.put_line(chainefinale);
      END;
    END;
    Après exécution il ressort exactament le même résultat, c'est a dire "KCAS:AB;SHGC:SHF;MTP:NP;MTP:NP;MTP:NP;MBCAS:A1A2;".
    Je penses m'être mal exprimé.
    Pour le cas du MTP il peut exister plusieurs résultat pour la valeur : 'MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP'

    Imaginons si MMTCP = aucune valeur MMTP = aucune valeur MMH3 = une valeur HMTP = aucune valeur HMH3 = aucune valeur et HMTCP = 1 valeur
    Alors je souhaite que le case s'arrête à la valeur du HMTP, pas besoin de ramener les autres valeurs.

    En espérant m'être fait mieux comprendre même si je suis conscient que ce cas est assez perplexe.

  13. #13
    Membre Expert
    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
    Par défaut
    Mais le CASE s'arrête dans tous les cas, ce qu'il y a c'est que le SELECT amène une nouvelle ligne ensuite avec MTP et vu que l'on est sur une boucle c'est logique de le traiter aussi.

    Pour y remédier, on peut imaginer 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
    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
    DECLARE CURSOR c IS 
      select * 
      from haplo 
      where notest IN('KCAS', 'MBCAS', 'SHGC', 'MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP', 'MSHGC') 
      and nunati = '0114035148'
      order by DECODE(notest 'KCAS', 0,'SHGC', 1,'MSHGC', 2,'MMTCP', 3,'MMTP', 4,'MMH3', 5,'HMTP', 6,'HMH3', 7,'HMTCP', 8,'MBCAS', 9, 99);
     
    BEGIN
      DECLARE 
      Nb_MTP NUMBER(3) := 0;
      varRESULTEST varchar2(1000) := NULL;
      varNOTEST varchar2(1000) := NULL;
      chainefinale varchar2(1000) := NULL;
      BEGIN
        FOR r in c 
        LOOP   
          --Affectation des valeurs pour regrouper les tests.
          varNOTEST :=
            CASE 
              WHEN r.NOTEST = 'KCAS' THEN 'KCAS'
              WHEN r.NOTEST = 'MBCAS' THEN 'MBCAS'
              WHEN r.NOTEST IN ('MSHGC', 'SHGC') THEN 'SHGC'
              WHEN r.NOTEST IN ('MMTCP', 'MMTP', 'MMH3', 'HMTP', 'HMH3', 'HMTCP') THEN 'MTP'
            END CASE;
     
          CASE
            --Cas 'SHGC' 
            WHEN (r.NOTEST = 'MSHGC' OR r.NOTEST = 'shgc') AND r.TYPTEST= 'H'  THEN         
              varRESULTEST :=
                CASE 
                  WHEN  r.RESULTEST = '0' THEN 'NP'
                  WHEN  r.RESULTEST = '0' THEN 'NP'
                  WHEN  r.RESULTEST = '0' THEN 'NP'
                  ELSE '??'
                END CASE;
            ELSE
              --Cas 'MTP'
              IF (Nb_MTF = 0) THEN
                varRESULTEST := 
                  CASE 
                    WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTF' THEN 'NP' 
                    WHEN r.NOTEST='MMTCP' AND r.RESULTEST='MTC' THEN 'Porteur'
     
                    WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPF' THEN 'NP'
                    WHEN r.NOTEST='MMTP' AND r.RESULTEST='MTPC' OR r.RESULTEST='MTP' THEN 'NP'
     
                    WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3F' THEN 'NP'
                    WHEN r.NOTEST='MMH3' AND r.RESULTEST='MH3C' OR r.RESULTEST='MH3S' THEN 'NP'
     
                    WHEN r.NOTEST='HMTCP' AND r.RESULTEST='0' THEN 'NP'
                    WHEN r.NOTEST='HMTCP' AND r.RESULTEST='1' OR r.RESULTEST='2' THEN 'Porteur'
     
                    ELSE NULL
                  END CASE;
                  IF (varRESULT IS NOT NULL) THEN
                    Nb_MTF := Nb_MTF + 1;
                  END IF;
              END IF;
            END CASE;         
          END;
     
          IF  varRESULTEST IS NOT NULL 
            THEN varRESULTEST := varNOTEST || ':' || varRESULTEST || ';';
            ELSE varRESULTEST := varNOTEST || ':' || r.RESULTEST || ';';
          END IF;
          chainefinale  := chainefinale  || varRESULTEST;
        END LOOP;
        dbms_output.put_line(chainefinale);
      END;
    END;

  14. #14
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 986
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par iKeyyZ Voir le message
    ...Mon message d'erreur est :

    Rapport d'erreur -
    ORA-06592: CASE introuvable lors de l'exécution de l'instruction CASE


    Je ne savais pas qu'Oracle avait autant d'humour dans ses messages d'erreur !


    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  15. #15
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Ce n'est pas Oracle, c'est de l'anglais, comprendre le premier CASE comme un nom, le second comme la fonction.

    C'est comme de créer une fonction FACTURE qui te ramène une facture et qu'en cas de NO_DATA_FOUND tu dises : "FACTURE introuvable dans l'utilisation de la fonction FACTURE"

Discussions similaires

  1. Problème requête SQL (Oracle -> MySQL)
    Par iliass001 dans le forum Requêtes
    Réponses: 1
    Dernier message: 10/04/2013, 09h10
  2. Problème requête SQL (Oracle -> MySQL)
    Par iliass001 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 08/04/2013, 16h21
  3. Problème PL/SQL Oracle
    Par bcy dans le forum PL/SQL
    Réponses: 4
    Dernier message: 20/05/2011, 10h36
  4. Problème requete SQL Oracle
    Par Yassoubxl dans le forum SQL
    Réponses: 4
    Dernier message: 04/02/2008, 16h51
  5. Problème PL/SQL Oracle 8
    Par alex007 dans le forum PL/SQL
    Réponses: 19
    Dernier message: 16/03/2006, 14h51

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