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 :

Requette PL/SQL - Oracle 8i


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
    Architecte réseau
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Par défaut Requette PL/SQL - Oracle 8i
    Bjr,

    J'ai un petit pb en PL/SQL, j'ai une requette avec cette jointure

    AND e2.val_rub = a.mot_fin_per

    Dans certain cas a.mot_fin_per est NULL et j'aurais besoin de sortir aussi ces enregistrements, mais je ne trouve pas comment faire

    Avec vous des idées ?

    Merci

  2. #2
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Par défaut
    La jointure externe est sans doute la solution à ton problème, mais il faudrait en dire un peur plus (ne serait-ce que la version que tu utilises)

  3. #3
    Membre averti
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Par défaut
    Merci mais j'avais essayé la jointure externe, mais çà ne marche pas

    J'utilise Oracle 8i

    Et voici mon script
    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
     
    SELECT DISTINCT a.struc_dads periode, a.dat_debut datdeb,
    a.mot_deb_per motdeb ,e1.lib_rub libmotdeb,
    a.dat_fin datfin,
    a.mot_fin_per motfin, e2.lib_rub libmotfin ,
    a.ind_valorise valorisation,
    c.num_employ, c.nom_employ, a.idf_agent, d.nom_usuel, d.nom_prenom, d.num_insee,
     d.cle_insee
    FROM gp.tdu_agtmot a, gp.emploi b, gp.employ c, gp.agtnat d,
    gp.rub_ref e1, gp.rub_ref e2
    WHERE a.num_employ = '01'
    AND c.num_employ = a.num_employ
    AND a.dat_debut >= '01/01/2005'
    /*AND a.dat_fin >= '01/01/2005'*/
    AND d.nom_usuel BETWEEN 'A' AND 'C'
    AND a.idf_agent = d.idf_agent
    AND a.idf_agent = b.idf_agent
    AND d.num_grpaie ='4'
    AND a.struc_dads = 'S41'
    AND e1.cod_rub = 'S41.G01.00.002'
    AND e1.val_rub = a.mot_deb_per
    AND e2.cod_rub = 'S41.G01.00.004'
    AND (e2.val_rub  = a.mot_fin_per (+)) 
    AND a.idf_agent = '1202'
    ORDER BY a.idf_agent, d.nom_usuel, c.nom_employ, a.struc_dads, a.dat_debut, a.dat_fin, a.mot_deb_per, a.mot_fin_per

  4. #4
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Par défaut
    Pense à indenter correctement ta requête en exemple, voici le minimum :

    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
    SELECT DISTINCT a.struc_dads periode, a.dat_debut datdeb, 
                    a.mot_deb_per motdeb ,e1.lib_rub libmotdeb, 
                    a.dat_fin datfin, 
                    a.mot_fin_per motfin, e2.lib_rub libmotfin , 
                    a.ind_valorise valorisation, 
                    c.num_employ, c.nom_employ, a.idf_agent, d.nom_usuel, 
                    d.nom_prenom, d.num_insee, d.cle_insee 
    FROM gp.tdu_agtmot a, gp.emploi b, gp.employ c, gp.agtnat d, 
         gp.rub_ref e1, gp.rub_ref e2 
    WHERE a.num_employ = '01' 
      AND c.num_employ = a.num_employ 
      AND a.dat_debut >= '01/01/2005' 
      /*AND a.dat_fin >= '01/01/2005'*/ 
      AND d.nom_usuel BETWEEN 'A' AND 'C' 
      AND a.idf_agent = d.idf_agent 
      AND a.idf_agent = b.idf_agent 
      AND d.num_grpaie ='4' 
      AND a.struc_dads = 'S41' 
      AND e1.cod_rub = 'S41.G01.00.002' 
      AND e1.val_rub = a.mot_deb_per 
      AND e2.cod_rub = 'S41.G01.00.004' 
      AND (e2.val_rub  = a.mot_fin_per (+)) 
      AND a.idf_agent = '1202' 
    ORDER BY a.idf_agent, d.nom_usuel, c.nom_employ, a.struc_dads,
             a.dat_debut, a.dat_fin, a.mot_deb_per, a.mot_fin_per
    Je me plantais toujours sur le côté où mettre le (+) (vive la syntaxe standard ), es-tu sur que tu l'a mise du bon côté ?
    Il faut ajouter le (+) partout ou ta table apparaît, par exemple si la jointure ne peut pas se faire sur le table e2, il est impossible que e2.cod_rub = 'S41.G01.00.004', puisque e2.cod_rub est NULL

  5. #5
    Membre averti
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Par défaut
    Citation Envoyé par Médiat
    Je me plantais toujours sur le côté où mettre le (+) (vive la syntaxe standard ), es-tu sur que tu l'a mise du bon côté ?
    Il faut ajouter le (+) partout ou ta table apparaît, par exemple si la jointure ne peut pas se faire sur le table e2, il est impossible que e2.cod_rub = 'S41.G01.00.004', puisque e2.cod_rub est NULL
    pour ta réponse !

    Désolé pour l'indentation

    Pour ce qui est du code, en fait c'est 'a.mot_fin_per' qui peut-être vide, la table e2 n'est jamais vide car c'est juste une table permettant de faire la correspondante en un code rubrique et un libellé

    Je rame très fort en ce lundi matin

  6. #6
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Par défaut
    Citation Envoyé par rjulie
    Pour ce qui est du code, en fait c'est 'a.mot_fin_per' qui peut-être vide, la table e2 n'est jamais vide car c'est juste une table permettant de faire la correspondante en un code rubrique et un libellé
    C'est parce que 'a.mot_fin_per' est NULL que tu n'as pas de lien sur e2, et donc e2.cod_rub est NULL (e2 ne pointe sur rien).

  7. #7
    Membre averti
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Par défaut
    Citation Envoyé par Médiat
    [C'est parce que 'a.mot_fin_per' est NULL que tu n'as pas de lien sur e2, et donc e2.cod_rub est NULL (e2 ne pointe sur rien).
    Exact, mais bon je vois pas comment me sortir de ce pb


  8. #8
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Citation Envoyé par Médiat
    C'est parce que 'a.mot_fin_per' est NULL que tu n'as pas de lien sur e2, et donc e2.cod_rub est NULL (e2 ne pointe sur rien).
    Euh, j'aurais plutôt dit que le problème venait de ces conditions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    AND a.dat_debut >= '01/01/2005' 
      /*AND a.dat_fin >= '01/01/2005'*/ 
    AND d.nom_usuel BETWEEN 'A' AND 'C' 
    AND a.idf_agent = d.idf_agent 
    AND a.idf_agent = b.idf_agent
    Car s'il ne trouve pas de a.mot_fin_per, il ne peut pas faire la jointure avec les tables b et d.

    Voici un post qui devrait t'aider à trouver une solution :
    http://www.developpez.net/forums/vie...84e955fa27c375

  9. #9
    Membre averti
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Par défaut
    Citation Envoyé par plaineR
    Voici un post qui devrait t'aider à trouver une solution :
    http://www.developpez.net/forums/vie...84e955fa27c375



    Merci, j'avais vu ta solution, je suis en train d'essayer de l'appliquer, mais c'est pas gagné

  10. #10
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Par défaut
    Citation Envoyé par plaineR
    Euh, j'aurais plutôt dit que le problème venait de ces conditions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    AND a.dat_debut >= '01/01/2005' 
      /*AND a.dat_fin >= '01/01/2005'*/ 
    AND d.nom_usuel BETWEEN 'A' AND 'C' 
    AND a.idf_agent = d.idf_agent 
    AND a.idf_agent = b.idf_agent
    Car s'il ne trouve pas de a.mot_fin_per, il ne peut pas faire la jointure avec les tables b et d.
    Je ne comprends pas : a.mot_fin_per à NULL ne veut pas dire que l'enregistrement n'existe pas, donc a.idf_agent peut très bien exister, et donc la jointure sur b et d se passer très bien, ce qui n'est pas le cas de la jointure sur e2 qui se fait au travers de ce fameux a.mot_fin_per ?

  11. #11
    Membre averti
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Par défaut
    Citation Envoyé par Médiat
    Je ne comprends pas : a.mot_fin_per à NULL ne veut pas dire que l'enregistrement n'existe pas, donc a.idf_agent peut très bien exister, et donc la jointure sur b et d se passer très bien, ce qui n'est pas le cas de la jointure sur e2 qui se fait au travers de ce fameux a.mot_fin_per ?
    Celà me semble beaucoup plus logique, en effet j'ai bien un enregistrement a.idf_agent, mais par contre je n'arrive pas à faire la liaison avec a.mot_fin_per qui est à NULL :-(

    Et je vois pas comment contourner le pb

  12. #12
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Par défaut
    Voila comment je ferais avec la syntaxe normée :

    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
    SELECT DISTINCT a.struc_dads periode, a.dat_debut datdeb, 
                    a.mot_deb_per motdeb ,e1.lib_rub libmotdeb, 
                    a.dat_fin datfin, 
                    a.mot_fin_per motfin, e2.lib_rub libmotfin , 
                    a.ind_valorise valorisation, 
                    c.num_employ, c.nom_employ, a.idf_agent, d.nom_usuel, 
                    d.nom_prenom, d.num_insee, d.cle_insee 
    FROM gp.tdu_agtmot a INNER JOIN gp.emploi b        ON a.idf_agent  = b.idf_agent
                         INNER JOIN gp.employ c        ON c.num_employ = a.num_employ
                         INNER JOIN gp.agtnat d        ON a.idf_agent  = d.idf_agent
                         INNER JOIN gp.rub_ref e1      ON e1.val_rub   = a.mot_deb_per
                         LEFT OUTER JOIN gp.rub_ref e2 ON e2.val_rub   = a.mot_fin_per AND e2.cod_rub = 'S41.G01.00.004'
    WHERE a.num_employ = '01' 
      AND a.dat_debut >= '01/01/2005' 
      /*AND a.dat_fin >= '01/01/2005'*/ 
      AND d.nom_usuel BETWEEN 'A' AND 'C' 
      AND d.num_grpaie ='4' 
      AND a.struc_dads = 'S41' 
      AND e1.cod_rub = 'S41.G01.00.002' 
      AND a.idf_agent = '1202' 
    ORDER BY a.idf_agent, d.nom_usuel, c.nom_employ, a.struc_dads, 
             a.dat_debut, a.dat_fin, a.mot_deb_per, a.mot_fin_per
    Les INNER JOIN sont faciles à traduire, le LEFT OUTER JOIN un peu moins (je ne sais jamais de quel côté mettre le (+).

    Le point le plus important est la présence de e2.cod_rub = 'S41.G01.00.004' dans le ON du LEFT OUTER JOIN et non dans le WHERE.
    c'est à dire :
    e2.cod_rub(+) = 'S41.G01.00.004'
    ou (je me plante tout le temps)
    e2.cod_rub = 'S41.G01.00.004'(+)

  13. #13
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Citation Envoyé par Médiat
    Je ne comprends pas : a.mot_fin_per à NULL ne veut pas dire que l'enregistrement n'existe pas, donc a.idf_agent peut très bien exister, et donc la jointure sur b et d se passer très bien, ce qui n'est pas le cas de la jointure sur e2 qui se fait au travers de ce fameux a.mot_fin_per ?
    Non, non, voici un petit exemple pour illustrer mes propos :
    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
    SQL> create table a (col1 varchar2(30), col2 varchar2(30));
    Table created.
     
    SQL> create table b (col1 varchar2(30), col2 varchar2(30));
    Table created.
     
    SQL> insert into a values ('a', 'A');
    1 row created.
     
    SQL> insert into a values ('b', 'B');
    1 row created.
     
    SQL> insert into b values ('a', '1');
    1 row created.
     
    SQL> select a.*, b.*
      2  from a, b
      3  where a.col1 = b.col1 (+);
     
    COL1 COL2 COL1 COL2
    ---- ---- ---- ----
    a    A    a    1
    b    B
    Quand tu fais une jointure externe, c'est toutes les autres colonnes de la table du côté où est la jointure externe qui sont nulles et non les colonnes de l'autre table

    Dans le cas de rjulie, la jointure avec les table b et d ne peut pas se faire si la jointure externe entre a et e ne sa fait pas puisque dans ce cas toutes le colonnes de a sont null.

    [EDIT] La remarque que je fais plus haut est par rapport à la requête que rjulie a écrite qui me semble d'ailleurs fausse, je ferais plutôt quelque chose comme cela :
    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
    SELECT DISTINCT a.struc_dads periode, a.dat_debut datdeb, 
                    a.mot_deb_per motdeb ,e1.lib_rub libmotdeb, 
                    a.dat_fin datfin, 
                    a.mot_fin_per motfin, e2.lib_rub libmotfin , 
                    a.ind_valorise valorisation, 
                    c.num_employ, c.nom_employ, a.idf_agent, d.nom_usuel, 
                    d.nom_prenom, d.num_insee, d.cle_insee 
    FROM gp.tdu_agtmot a, gp.emploi b, gp.employ c, gp.agtnat d, 
         gp.rub_ref e1, gp.rub_ref e2 
    WHERE a.num_employ = '01' 
      AND c.num_employ = a.num_employ 
      AND a.dat_debut >= '01/01/2005' 
      /*AND a.dat_fin >= '01/01/2005'*/ 
      AND d.nom_usuel BETWEEN 'A' AND 'C' 
      AND a.idf_agent = d.idf_agent 
      AND a.idf_agent = b.idf_agent 
      AND d.num_grpaie ='4' 
      AND a.struc_dads = 'S41' 
      AND e1.cod_rub = 'S41.G01.00.002' 
      AND e1.val_rub = a.mot_deb_per 
      AND e2.cod_rub(+) = 'S41.G01.00.004' 
      AND (e2.val_rub(+)  = a.mot_fin_per) 
      AND a.idf_agent = '1202' 
    ORDER BY a.idf_agent, d.nom_usuel, c.nom_employ, a.struc_dads, 
             a.dat_debut, a.dat_fin, a.mot_deb_per, a.mot_fin_per
    [/EDIT]

  14. #14
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Par défaut
    PlaineR >> tu me fais soupçonner de plus en plus que je ne suis pas le seul à ne pas me rappeler de quel côté mettre le (+), et que je partage ce handicap avec rjulie
    La réponse serait alors dans :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AND e2.cod_rub(+) = 'S41.G01.00.004' 
    AND e2.val_rub(+)  = a.mot_fin_per
    Je ne peux pas faire de test avant ce soir, pourrais-tu (si tu as le temps ) ajouter une ligne dans la table a et ré-exécuter ton SELECT

    insert into a values (NULL, 'C');

    si je ne me trompe pas trop, tu devrais trouver :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    COL1 COL2 COL1 COL2 
    ---- ---- ---- ---- 
    a    A    a    1 
    b    B
         C

    [EDIT]
    Nous sommes d'accord
    Laisse tomber le test
    [/EDIT]

  15. #15
    Membre averti
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Par défaut
    pour vos réponses

    La solution est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    AND e2.cod_rub (+) = 'S41.G01.00.004'
    AND e2.val_rub (+) = mot_fin_per
    La morale de cette histoire c'est que je risque de me planter encore longtemps avec les (+)

    Merci encore

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

Discussions similaires

  1. [PL/SQL - Oracle 9i] CLOB et owa_pattern
    Par rebolon dans le forum Oracle
    Réponses: 9
    Dernier message: 18/11/2004, 15h28
  2. Réponses: 4
    Dernier message: 18/10/2004, 16h18
  3. Generer du xml via SQL(oracle) avec de l'asp
    Par jpg dans le forum XQUERY/SGBD
    Réponses: 6
    Dernier message: 03/08/2004, 12h36
  4. [SQL ORACLE] Soustraction de deux timestamps
    Par platinum07 dans le forum SQL
    Réponses: 34
    Dernier message: 02/07/2004, 10h42
  5. PL/SQL ORACLE (Record Dans un Varchar2)
    Par argoet dans le forum PL/SQL
    Réponses: 24
    Dernier message: 14/05/2004, 16h06

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