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

SQL Oracle Discussion :

[PL/SQL] Problème gestion d'éxception


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Février 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Février 2007
    Messages : 26
    Par défaut [PL/SQL] Problème gestion d'éxception
    Bonjour à tous,

    J' ai un problème pour gérer une éxception dans une fonction en PL/SQL.
    Ma fonction parcours une table, doit me selectionner la plus grande date contenue dans cette table pour un client donné et la soustraire à la date du jour. Le code de cette fonction marche tres bien quand je l'appelle en JAVA. Le problème, c'est quand le client n'est pas encore dans la table, c'est-à-dire qu'il n'y a pas de date lui corréspondant, un éxception est levée sous Eclipse, qui m'indique qu'aucune valeur n'est retournée, mais le programme continu à tourner sans problème. Je voudrais qu'il n'y ait plus d'affichage.
    C'est pourquoi j'ai décidé de gérer l'éxception en PL/SQL.

    Voici mon code :
    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
     
    CREATE OR REPLACE FUNCTION EmpecheVote (loginUtil IN CLIENT.login%type) RETURN INTEGER IS 
    BEGIN 
    DECLARE 
    presant INTEGER;
    i INTEGER;
    k INTEGER;
    temp DATE;
    CURSOR monC IS SELECT DateNote FROM TempIndFilm WHERE loginNoteur = loginUtil;
    TYPE TableDate IS Table Of DATE INDEX BY BINARY_INTEGER;
    tabdate TableDate;
    BEGIN
    presant:=-1;
    k:=0;
    i:=0;
    FOR elt in monC 
    LOOP
    tabdate(i):=TO_DATE(elt.DateNote);
    i:=i+1;
    END LOOP;
    temp:=tabDate(0);
    FOR i IN 1..tabdate.COUNT() -1 
    LOOP
    IF tabdate(i) > temp THEN
    temp:=tabdate(i); 
    END IF;
    END LOOP;
    IF (SYSDATE - temp>1) THEN
    presant:=1;
    END IF;
    EXCEPTION 
    WHEN NO_DATA_FOUND THEN
    presant:=0;
    return presant;
    END;
    END EmpecheVote;
    /
    Le probleme avec cette exception, c'est que maintenant mon code ne marche plus, la valeur retournée est incorrecte, il me retourne tout le temps 0.

    J'aimerais savoir si l'erreur vient de la synthaxe de mon éxception ou si elle est male placée...

  2. #2
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    il manque un RETURN presant non ?

    Sinon, à ce que je vois l'exception ne se déclenchera jamais

    c'est monC%ROWCOUNT éventuellement que tu devrais utiliser.

    PS : presant s'écrit present

  3. #3
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Trop de code, trop des variables, trop des exceptions, etc.
    L'exception NO_DATA_FOUND n'est jamais levé pour un curseur, il faut faire un «*select ... into*» pour ça.
    Select Max(...) permet d'obtenir la plus grande date par client pas besoin de recoder l'algorithme.
    Vue le code que vous avez posté vous avez du travaille à faire avec SQL

  4. #4
    Membre averti
    Inscrit en
    Février 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Février 2007
    Messages : 26
    Par défaut
    Le problème pour le select MAX, c'est que j'ai stockée les date en CHAR dans la table et non pas en DATE, c'est pourquoi j'utilise un tableau pour convertir les CHAR en DATE. Maintenant, est-ce que la fonction MAX marche aussi avec les variables de tye CHAR.

    Sinon orafrance, j'ai essayé d'utilisé monC%ROWCOUNT comme 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
     
    CREATE OR REPLACE FUNCTION EmpecheVote (loginUtil IN CLIENT.login%type) RETURN INTEGER IS 
    BEGIN 
    DECLARE 
    presant INTEGER;
    i INTEGER;
    k INTEGER;
    temp DATE;
    CURSOR monC IS SELECT DateNote FROM TempIndFilm WHERE loginNoteur = loginUtil;
    TYPE TableDate IS Table Of DATE INDEX BY BINARY_INTEGER;
    tabdate TableDate;
    BEGIN
    presant:=-1;
    k:=0;
    i:=0;
    IF monC%ROWCOUNT IS NULL THEN 
    presant:=0;
    ELSE 
    	FOR elt in monC 
    	LOOP
    	tabdate(i):=TO_DATE(elt.DateNote);
    	i:=i+1;
    	END LOOP;
    	temp:=tabDate(0);
    	FOR i IN 1..tabdate.COUNT() -1 
    	LOOP
    	IF tabdate(i) > temp THEN
    	temp:=tabdate(i); 
    	END IF;
    	END LOOP;
    	IF (SYSDATE - temp>1) THEN presant:=1;
    	END IF;
    END IF;
    return presant;
    END;
    END EmpecheVote;
    /
    A l'éxécution avec Eclipse, j'ai une éxception qui est levée: "curseur non valide" à la ligne du ROWCOUNT.

  5. #5
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    et MAX(TO_DATE(colonne)) ? T'es juste en train de réinventer la roue

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    354
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 354
    Par défaut
    Citation Envoyé par orafrance Voir le message
    et MAX(TO_DATE(colonne)) ? T'es juste en train de réinventer la roue
    En plus ce n'est pas bien de stocker les dates en char dans les tables

  7. #7
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par Rydley Voir le message
    ...
    Sinon orafrance, j'ai essayé d'utilisé monC%ROWCOUNT comme 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
     
    CREATE OR REPLACE FUNCTION EmpecheVote (loginUtil IN CLIENT.login%type) RETURN INTEGER IS 
    BEGIN 
    DECLARE 
    presant INTEGER;
    i INTEGER;
    k INTEGER;
    temp DATE;
    CURSOR monC IS SELECT DateNote FROM TempIndFilm WHERE loginNoteur = loginUtil;
    TYPE TableDate IS Table Of DATE INDEX BY BINARY_INTEGER;
    tabdate TableDate;
    BEGIN
    presant:=-1;
    k:=0;
    i:=0;
    IF monC%ROWCOUNT IS NULL THEN 
    presant:=0;
    ELSE 
    	FOR elt in monC 
    	LOOP
    	tabdate(i):=TO_DATE(elt.DateNote);
    	i:=i+1;
    	END LOOP;
    	temp:=tabDate(0);
    	FOR i IN 1..tabdate.COUNT() -1 
    	LOOP
    	IF tabdate(i) > temp THEN
    	temp:=tabdate(i); 
    	END IF;
    	END LOOP;
    	IF (SYSDATE - temp>1) THEN presant:=1;
    	END IF;
    END IF;
    return presant;
    END;
    END EmpecheVote;
    /
    A l'éxécution avec Eclipse, j'ai une éxception qui est levée: "curseur non valide" à la ligne du ROWCOUNT.
    C'est normal. Le curseur n'est pas ouvert. En plus le ROWCOUNT n'est jamais null. Et tu continue a copier le données dans un tableau inutilement. Cette fonction n’a pas besoin de plus de 5 lignes de code.
    Bon tu progresse déjà il n’y plus l’exception NO_DATA_FOUND. Elimine le tableau tabData, le variables i, k, temp, employe Max et tu verra.

  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 mieux est de tout faire dans 1 select

    Il faut bien déterminer les règles :
    De ce que j'ai vu, il y a 3 valeurs de retour
    0 Si pas de ligne
    -1 Si le max date de plus de 1 jour
    1 Si le max date de moins de 1 jour (ou plus tard qu'aujourdh'ui)

    Un petit decode pour sortir ça.
    Avec
    Count(*) pour avoir le nb de lignes
    Sign(a-b) qui renvoit 1 sur a>b
    Max(to_date(date_en_char, 'DD/MM/YYYY'))

    Ou alors utiliser un CASE (Plus simple à coder et à lire)

  9. #9
    Membre averti
    Inscrit en
    Février 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Février 2007
    Messages : 26
    Par défaut
    C'est bon j'ai reussi a résoudre mon problème. J'ai utilisé ce que m'a dit orafrance, j'ai fait un MAX(TO_DATE(colonne)), ce qui a grandement simplifiée ma requête. Merci a tous pour votre aide.

    Voici mon code final:

    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
     
    CREATE OR REPLACE FUNCTION EmpecheVote (loginUtil IN CLIENT.login%type) RETURN INTEGER IS 
    BEGIN 
    DECLARE 
    presant INTEGER;
    temp DATE;
    dateNote DATE;
    BEGIN
    presant:=-1;
    SELECT MAX (TO_DATE (DateNote)) INTO dateNote FROM TempIndFilm WHERE loginNoteur = loginUtil;
     
    IF dateNote IS NULL THEN 
    presant:=0;
    ELSE 
    	temp:=dateNote;
    	IF (SYSDATE - temp>1) THEN presant:=1;
    	END IF;
    END IF;
    return presant;
    END;
    END EmpecheVote;
    /

  10. #10
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Il reste encore trop des variables et trop de code. Nvl permet de traiter les nulles, Decode ou Case permet de éliminer les If et le Begin suivi de Declare et de Begin laisse une mauvais impression.

  11. #11
    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
    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
    CREATE OR REPLACE FUNCTION EmpecheVote (loginUtil IN CLIENT.login%TYPE) RETURN INTEGER IS 
    	presant INTEGER;
    BEGIN
    	presant:=-1;
    	BEGIN
    		SELECT (CASE WHEN COUNT(*) = 0 THEN 0
    			WHEN MAX(TO_DATE (DateNote)) - SYSDATE > 1 THEN 1
    			ELSE -1 END)  AS presant
    		INTO presant
    		FROM TempIndFilm 
    		WHERE loginNoteur = loginUtil;
    	EXCEPTION WHEN OTHERS THEN NULL;
    	END;
     
    	RETURN presant;
     
    END EmpecheVote;
    /

  12. #12
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par McM Voir le message
    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
    CREATE OR REPLACE FUNCTION EmpecheVote (loginUtil IN CLIENT.login%TYPE) RETURN INTEGER IS 
    	presant INTEGER;
    BEGIN
    	presant:=-1;
    	BEGIN
    		SELECT (CASE WHEN COUNT(*) = 0 THEN 0
    			WHEN MAX(TO_DATE (DateNote)) - SYSDATE > 1 THEN 1
    			ELSE -1 END)  AS presant
    		INTO presant
    		FROM TempIndFilm 
    		WHERE loginNoteur = loginUtil;
    	EXCEPTION WHEN OTHERS THEN NULL;
    	END;
     
    	RETURN presant;
     
    END EmpecheVote;
    /
    When OTHERS THEN NULL ça j'aime pas du tout

  13. #13
    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

Discussions similaires

  1. [SQL] Problème gestion doublons
    Par Sh4dow49 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 02/05/2007, 19h47
  2. [SQL] problème pour faire ma requete
    Par seb.briet dans le forum Langage SQL
    Réponses: 4
    Dernier message: 29/12/2004, 16h51
  3. [PL/SQL] problème de trigger
    Par Chuck67 dans le forum Oracle
    Réponses: 14
    Dernier message: 09/12/2004, 23h17
  4. [SQL] problème avec les date et les group By
    Par Stef784ever dans le forum Langage SQL
    Réponses: 3
    Dernier message: 23/11/2004, 09h18
  5. [Debutant][Join Sql] problème de join
    Par ultimax dans le forum Langage SQL
    Réponses: 4
    Dernier message: 16/11/2004, 12h01

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