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 :

Fonction EXISTS ou SQL%FOUND


Sujet :

PL/SQL Oracle

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2017
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2017
    Messages : 176
    Points : 58
    Points
    58
    Par défaut Fonction EXISTS ou SQL%FOUND
    Bonjour,

    Je cherche à faire une procédure une stockée dans laquelle je voudrais effectuer deux traitements (select) l'un en fonction de l'autre. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Select ch1, ch2, ch3
    Into var1, var2, var3
    From table1
    Where id = p_id;
    si et seulement si la première requête ne retourne rien que j'exécute ma deuxième requête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Select ch1, ch2, ch3
    Into var1, var2, var3
    From table2
    Where id = p_id;
    J'ai utilisé les fonctions SQL%NOTFOUND et EXISTS mais ça n'a pas fonctionné.

    J'aurais pu définir une variable mais étant donné que je récupère déjà d'autres variables dans mes requêtes à l'aide de into. Je ne sais pas où placer la variable into v_count.

    Merci pour votre aide.

  2. #2
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Bonjour,

    Sur ton premier "select", place le dans un bloc façon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    BEGIN
    ...
    EXCEPTION
        WHEN NO_DATA_FOUND
        THEN
            ...
    END;
    Si pas de données trouvées lors du premier "select", alors tu peux décider de la suite.

    @+

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2017
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2017
    Messages : 176
    Points : 58
    Points
    58
    Par défaut
    Merci pour votre réponse.

    Si je comprends bien, j'exécute ma deuxième requête dans la partie exception après le then?

  4. #4
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Techniquement, c'est possible.
    Perso, je me ferais une variable du genre (par exemple):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    l_no_data_in_first_query VARCHAR2(1 CHAR) DEFAULT 'N';
    que je passerais a 'Y' dans le cas the NO_DATA_FOUND, et que je testerais ensuite pour executer ou non la seconde requête.

    Surtout que pour ta seconde requête, tu fais aussi un "select into", donc tu vas devoir selon moi a nouveau repasser par un BEGIN...EXCEPTION ... afin de catcher les erreurs, etc

  5. #5
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 106
    Points : 28 394
    Points
    28 394
    Par défaut
    Tu peux aussi le faire en une seule 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
    SELECT ch1, ch2, ch3
    INTO var1, var2, var3
    FROM    (   SELECT ch1, ch2, ch3
                FROM table1
                WHERE id = p_id
            UNION
                SELECT ch1, ch2, ch3
                FROM table2
                WHERE id = p_id
                WHERE   NOT EXISTS
                        (   SELECT  NULL
                            FROM    table1
                            WHERE   table1.id   = table2.id
                        )
            )
    ;

  6. #6
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2017
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2017
    Messages : 176
    Points : 58
    Points
    58
    Par défaut
    Merci pour vos réponses.

    Dans le cas d'une seule requête je ne vois pas comment ça peut effectuer le traitement souhaité.

    Le seul point commun entre les requêtes est le paramètre p_id.

    Je devrais à tout prix exécuter la deuxième requête si la première ne retourne aucune valeur et retourner un message d'erreur dans le cas où les 2 ne retournent rien.

    Dans le cas où une des 2 retourne quelque chose, je récupère les valeurs.

  7. #7
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Bonjour,

    Si effectivement les 2 requêtes peuvent être mises en relation (ce que je n'avais pas pris en compte), alors faire tout d'un seul trait comme le propose al1_24 est certainement une bonne chose.
    Il n'y a que toi qui puisse le dire, car tu as la logique fonctionnelle, nous pas.
    De ce fait, tu n'auras qu'a "catcher" les erreurs en cas de NO_DATA_FOUND sur cette unique requête, et puis en fonction de ce qui se passe soit renvoyer les données, soit un message approprié si pas de données.

    @+

  8. #8
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 338
    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 338
    Points : 39 726
    Points
    39 726
    Billets dans le blog
    9
    Par défaut
    Bonsoir,

    Autre solution : utiliser la fonction coalesce avec le résultat des deux requetes, le 1er résultat non nul sera retourné

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 72
    Points : 72
    Points
    72
    Par défaut
    Bonjour
    A moins que tu ne cherches ailleurs que dans les pays CA, puis US, pourquoi ne partirais-tu pas sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	SELECT CITY, COUNTRY_ID
    	FROM LOCATIONS
    	WHERE POSTAL_CODE = '12345'
    	ORDER BY DECODE( COUNTRY_ID, 'CA', 1, 'US', 2, 3 ) ;
    la requête tenteras toujours de te retourner le 'CA', à défaut les 'US', ou à défaut le premier pays qui matchera avec le code postal


    Oliv

  10. #10
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2017
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2017
    Messages : 176
    Points : 58
    Points
    58
    Par défaut
    Je remets le message que j'ai supprimé précédent votre message.

    Bonjour,

    Merci à tous pour vos réponses.

    Un exemple plus concret de ce que je veux.

    Requête 1:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        SELECT CITY
         -- INTO P_CITY
          FROM LOCATIONS
          WHERE POSTAL_CODE = P_POSTAL
          AND COUNTRY_ID = 'CA';
    Requête 2:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        SELECT CITY
         -- INTO P_CITY
          FROM LOCATIONS
          WHERE POSTAL_CODE = P_POSTAL
          AND COUNTRY_ID = 'US';
    J'ai en paramètre d'entrée le code postal et au cas où la première requête ne retourne rien j'exécute la seconde requête en utilisant un autre country_id.

    Devrais-je plutôt utiliser la fonction coalesce ou la solution proposée par al1_24?

    Est ce que cela est correcte ?

    Solution 1 :

    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
    SELECT CITY
        --INTO P_CITY
        FROM ( SELECT CITY
               FROM LOCATIONS
               WHERE POSTAL_CODE = P_POSTAL
               AND COUNTRY_ID ='CA'
               UNION
               SELECT CITY
               --INTO P_CITY
               FROM LOCATIONS
               WHERE POSTAL_CODE = P_POSTAL
               AND COUNTRY_ID = 'US'
               AND NOT EXISTS
               (
               SELECT NULL
                FROM LOCATIONS
                WHERE POSTAL_CODE = P_POSTAL
               AND COUNTRY_ID = 'CA'
               )
        );
    Solution 2

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT COALESCE((SELECT CITY
        FROM LOCATIONS
        WHERE POSTAL_CODE = '261923'
        AND COUNTRY_ID = 'CA'), 
       (SELECT CITY
        FROM LOCATIONS
        WHERE POSTAL_CODE = '261923'
        AND COUNTRY_ID = 'US')) CITY
    FROM DUAL;
    Merci,

  11. #11
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2017
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2017
    Messages : 176
    Points : 58
    Points
    58
    Par défaut
    Les conditions peuvent changer à tout moment excepté le postal_code qui correspond au paramètre d'entrée commun aux deux requêtes.

  12. #12
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2017
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2017
    Messages : 176
    Points : 58
    Points
    58
    Par défaut
    Citation Envoyé par al1_24 Voir le message
    Tu peux aussi le faire en une seule 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
    SELECT ch1, ch2, ch3
    INTO var1, var2, var3
    FROM    (   SELECT ch1, ch2, ch3
                FROM table1
                WHERE id = p_id
            UNION
                SELECT ch1, ch2, ch3
                FROM table2
                WHERE id = p_id
                WHERE   NOT EXISTS
                        (   SELECT  NULL
                            FROM    table1
                            WHERE   table1.id   = table2.id
                        )
            )
    ;
    Je me suis trompé dans mon exemple. Il s'agit de deux requêtes qui pointent vers la même table et ce qui les différencie c'est au niveau du country_id par ex:

    Requête 1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     SELECT CITY
         -- INTO P_CITY
          FROM LOCATIONS
          WHERE POSTAL_CODE = P_POSTAL
          AND COUNTRY_ID = 'CA';
    Requête 2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     SELECT CITY
         -- INTO P_CITY
          FROM LOCATIONS
          WHERE POSTAL_CODE = P_POSTAL
          AND COUNTRY_ID = 'US';
    ça peut être autre chose comme condition mais la table est la même et le select into est le même.

    Sinon j'ai utilisé la fonction coalesce proposée par @escartefigue comme ceci et ça a l'air de bien fonctionner mais j'aurais voulu essayer la proposition de @al1_24 et savoir aussi si un decode peut faire l'affaire comme le propose @olive-andre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT COALESCE((SELECT CITY
        FROM LOCATIONS
        WHERE POSTAL_CODE = '26192'
        AND COUNTRY_ID = 'CA'), 
       (SELECT CITY
        FROM LOCATIONS
        WHERE POSTAL_CODE = '26192'
        AND COUNTRY_ID = 'US'), '0') CITY
    FROM DUAL;
    Merci,

Discussions similaires

  1. Fonction exists de SQL
    Par EkrazNeophite dans le forum PHP & Base de données
    Réponses: 18
    Dernier message: 18/02/2015, 15h10
  2. [2008] Tester l'existence d'une fonction en Transact SQL
    Par bza88 dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 20/11/2014, 17h09
  3. fonction exists toujours vrai transact sql
    Par bobby51 dans le forum Développement
    Réponses: 6
    Dernier message: 27/03/2009, 11h09
  4. Fonction "Format" sous SQL
    Par Fabby69 dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 08/10/2004, 09h07
  5. fonction left avec sql server 6.5
    Par shake dans le forum Langage SQL
    Réponses: 2
    Dernier message: 29/06/2004, 08h48

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