Précédent   Forum des professionnels en informatique > Bases de données > Oracle > PL/SQL
PL/SQL Forum d'entraide sur le PL/SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/01/2012, 12h30   #1
Invité de passage
 
Femme Gaelle
Étudiant
Inscription : janvier 2012
Messages : 2
Détails du profil
Informations personnelles :
Nom : Femme Gaelle
Localisation : France

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

Informations forums :
Inscription : janvier 2012
Messages : 2
Points : 0
Points : 0
Par défaut Problème exception [ PL SQL , Oracle]

Salut tout le monde,

J'ai une vue "author_novel" qui contient deux colonnes : noms des auteurs "author_name", et les noms de leurs romans "novel_title". j'ai saisi cette procédure afin de pouvoir, quand j'entre le nom d'un auteur, afficher la liste de toutes ses œuvres :
Code :
1
2
3
SELECT author_name || ' ' || novel_title
  FROM author_novel
 WHERE author_name = '&name';
Si le nom de l'auteur est correctement saisi, tout va bien, la liste s'affiche. sinon, ca dit qu'il y a zéro ligne.

À la place de ce deuxième cas (0 ligne), je souhaite saisir une instruction qui me permettra de dire "il y a erreur, veuillez ressaisir le nom de l'auteur", peut-être à l'aide d'une exception, ou d'un trigger ?

Pouvez vous m'aider s'il vous plait ?

Merci d'avance.
gaellegeek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 10h44   #2
Membre Expert
 
Avatar de lola06
 
Femme Laure
Consultante en Business Intelligence
Inscription : avril 2007
Messages : 983
Détails du profil
Informations personnelles :
Nom : Femme Laure
Âge : 25
Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Consultante en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : avril 2007
Messages : 983
Points : 1 693
Points : 1 693
Tu pourrais peut-être faire quelque chose du style :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT count(*) into v_cnt
FROM author_novel
WHERE author_name = v_name;
 
IF v_cnt = 0 THEN
 
     v_txt = 'il y a erreur, veuillez ressaisir le nom de l'auteur';
 
ELSE 
 
    SELECT author_name || ' ' || novel_title into v_txt
    FROM author_novel
    WHERE author_name = v_name;
 
END IF;
Par contre
__________________
~ Lola ~

Ne pas oublier :
et aussi :
lola06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 11h03   #3
Invité de passage
 
Femme Gaelle
Étudiant
Inscription : janvier 2012
Messages : 2
Détails du profil
Informations personnelles :
Nom : Femme Gaelle
Localisation : France

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

Informations forums :
Inscription : janvier 2012
Messages : 2
Points : 0
Points : 0
OK, je vais essayer ce soir, et te répondre.

Merci
gaellegeek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2012, 11h32   #4
Invité régulier
 
Homme F.C
Développeur Décisionnel
Inscription : janvier 2012
Messages : 4
Détails du profil
Informations personnelles :
Nom : Homme F.C

Informations professionnelles :
Activité : Développeur Décisionnel

Informations forums :
Inscription : janvier 2012
Messages : 4
Points : 5
Points : 5
Bonjour, voici une autre solution pour diversifier les approches que vous pourriez voir:

Le principe est le suivant: N'afficher votre message d'erreur que si le drapeau de vérification d’existence de lignes ne passe pas à TRUE. (La boucle du IMPLICIT FOR CURSOR n'étant exécutée qu'en cas de présence de données).

Renseignez-vous quand même sur les restrictions du package DBMS_OUTPUT (Activation, taille du buffer pour ne pas avoir de surprises).

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
----------------------------------------------------------------
-- Création de la table
----------------------------------------------------------------
CREATE TABLE author_novel AS
SELECT 'AUTHOR_' || level AS author_name, 'NOVEL_' || level AS novel_title
FROM DUAL
CONNECT BY ROWNUM < 11;
 
----------------------------------------------------------------
-- Requête des données (V1)
----------------------------------------------------------------
DECLARE
   l_exists BOOLEAN := FALSE;
BEGIN
   -- Parcours des données du curseur implicite
   FOR c_novels IN (SELECT author_name || ' ' || novel_title AS disp_author_novel
                    FROM   author_novel
                    WHERE  author_name = '&author') LOOP
      -- Affichage du champ "disp_author_novel" en provenance du curseur
      dbms_output.put_line(c_novels.disp_author_novel);
      l_exists := TRUE; -- Répété à chaque ocurrence. Aucun impact majeur cependant
   END LOOP;
 
   -- Affichage d'une ligne d'erreur en cas d'absence de lignes
   IF NOT l_exists THEN
      dbms_output.put_line('Il y a erreur, veuillez ressaisir le nom de l''auteur');
   END IF;
   EXCEPTION
     WHEN OTHERS THEN
       -- Ajouter sa gestion des erreurs si besoin à la place du RAISE si besoin
       RAISE;    
END;
/
 
-- Testé avec AUTHOR_1 par exemple
 
----------------------------------------------------------------
-- Suppression de la table
----------------------------------------------------------------
DROP TABLE author_novel;
Zyniel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2012, 12h06   #5
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
C'est bien compliqué tout ça.
Oracle fournit l'exception NO_DATA_FOUND quand une requête ne ramène rien :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
declare
    v$_txt varchar2(10);
 
begin
    SELECT 'TOTO' INTO v$_txt
      FROM dual
     WHERE 1=0;
 
     dbms_output.put_line('OK : ' || v$_txt);
 
  exception when no_data_found then
     v$_txt := 'VIDE';
     dbms_output.put_line('KO : ' || v$_txt);
end;
/
 
 
KO : VIDE
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 21
Vieux 25/01/2012, 14h18   #6
Invité régulier
 
Homme F.C
Développeur Décisionnel
Inscription : janvier 2012
Messages : 4
Détails du profil
Informations personnelles :
Nom : Homme F.C

Informations professionnelles :
Activité : Développeur Décisionnel

Informations forums :
Inscription : janvier 2012
Messages : 4
Points : 5
Points : 5
La réponse précédente ne fonctionnera que dans le cas d'un auteur ayant UNE ou AUCUNE œuvre ce qui ne correspond pas à la requête initiale (Sauf si les noms des romans sont déjà concaténés en une seule ligne et que nous sommes assurés que pour chaque auteur la vue ne retourne au plus qu'une seule ligne):

Citation:
et les noms de leurs romans "novel_title"
Citation:
Si le nom de l'auteur est correctement saisi, tout va bien, la liste s'affiche
Il est donc nécessaire de traiter le cas d'un retour de lignes multiple depuis une requête SELECT ce qui ne fonctionnera pas dans le cas précédent si plus d'une ligne est retournée.

Citation:
http://docs.oracle.com/cd/B12037_01/...3_elems045.htm
By default, a SELECT INTO statement must return only one row. Otherwise, PL/SQL raises the predefined exception TOO_MANY_ROWS and the values of the variables in the INTO clause are undefined. Make sure your WHERE clause is specific enough to only match one row.
Ne jamais hésiter à enrichir avec les informations sur les cardinalités des tables et les relations entre les objets sous-jacents !

A noter qu'il y a au moins une multitudes de manières de traiter le cas précédent.
Zyniel est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2012, 15h33   #7
Membre Expert
 
Inscription : août 2009
Messages : 779
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 779
Points : 1 098
Points : 1 098
Ce genre de choses est du domaine de l'affichage. Le programme appelant (que ça soit du Java, une page php, etc.) devrait faire lui même le boulot : si le curseur retourné contient 0 lignes, il affiche le message d'erreur invitant à changer le nom sélectionné.
Rei Ichido est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/01/2012, 16h04   #8
Invité régulier
 
Homme F.C
Développeur Décisionnel
Inscription : janvier 2012
Messages : 4
Détails du profil
Informations personnelles :
Nom : Homme F.C

Informations professionnelles :
Activité : Développeur Décisionnel

Informations forums :
Inscription : janvier 2012
Messages : 4
Points : 5
Points : 5
Citation:
Envoyé par Rei Ichido Voir le message
Ce genre de choses est du domaine de l'affichage. Le programme appelant (que ça soit du Java, une page php, etc.) devrait faire lui même le boulot : si le curseur retourné contient 0 lignes, il affiche le message d'erreur invitant à changer le nom sélectionné.
Judicieusement rappelé. Les deux programmes proposés avec DBMS_OUTPUT sont plutôt orientés script SQL*PLUS (entre autres) et autres programmes Oracles se reposant sur ce type de sortie.

Ceci dit, en lisant l'énoncé celà ressemble fortement à une sortie de type SQL*Plus avec le scénario suivant:
Citation:
SQL> select * from author_novel;

AUTHOR_NAME NOVEL_TITLE
-------------- -------------
AUTHOR_1 NOVEL_1
...
AUTHOR_10 NOVEL_10

10 ligne(s) sélectionnée(s).
Et

Citation:
SQL> select * from author_novel where 1=0;

aucune ligne sélectionnée
"gaellegeek", peux tu préciser la notion de "j'ai saisi cette procédure" en nous donnant le contexte de l'appel ( Script SQL, Java, autre ? ), car le terme procédure en donnant une simple instruction SQL porte à confusion
Zyniel est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



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


 
 
 
 
Partenaires

Hébergement Web