Proc PLSQL et exception

Fermé
gegecret Messages postés 2 Date d'inscription mercredi 20 janvier 2010 Statut Membre Dernière intervention 21 janvier 2010 - 20 janv. 2010 à 17:46
 fiu - 23 janv. 2010 à 19:43
Bonjour,

alors voila,
j'ai un procédure (appelons la proc1) qui fait plein de choses, dont un dbms_snapshot.refresh, et puis à la fin, j'ai mis un pavé exception pour récupérer l'erreur oracle au cas où ...

et puis cette proc1 est appeler à partir d'une seconde procédure (que l'on appelera proc2). la proc2 permet d'exécuter plusieurs fois la proc1 avec un paramètre récupéré dans un curseur.

en gros :

procedure proc2
begin
open curseur
proc1(variable)
close curseur
end;

Sur le principe, celà fonctione, sauf quand il y a un erreur dans la proc1 (a cause du dbms_snapshot.refresh), car l'erreur n'est pas catché dans le pavé exception de la proc1, mais bien dans la proc principale proc2.

Alors pourriez vous me dire pourquoi ?
et surtout comment faire pour que l'erreur soit attrapé dans la proc1, et non dans la proc2
merci

5 réponses

Salut,

tu pourrais nous montrer comment tu attrapes tes exceptions dans proc1 ?
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
20 janv. 2010 à 18:14
Bonjour Gegecret,

Les erreurs se propagent du niveau "le plus imbriqué" vers le "niveau englobant".
Si dans proc1, tu n'as pas géré l'exception, celle-ci est alors propagée vers le niveau englobant, en l'occurrence proc2 ... et ainsi de suite.


Il te suffit donc de gérer l'erreur concernant le refresh dans proc1 pour ne pas te retrouver "téléporter par erreur (sans jeu de mots)" dans proc2.
0
gegecret Messages postés 2 Date d'inscription mercredi 20 janvier 2010 Statut Membre Dernière intervention 21 janvier 2010
21 janv. 2010 à 09:14
Bonjour,

Merci pour vos réponses, pourtant je pensé avoir positionné une exception correcte dans le proc1, que voici :

create or replace procedure MAPROC (nom_snapshot in varchar2) is
ladate varchar2(20);
BEGIN
select sysdate into ladate from dual;
dbms_snapshot.refresh(nom_snapshot);
execute immediate 'UPDATE update_snapshot set DATE_REFRESH = to_date(''' || ladate || ''') where nom_snapshot = '''|| nom_snapshot || '''';
COMMIT;
EXCEPTION
WHEN OTHERS THEN
execute immediate 'UPDATE update_snapshot set ERREUR = ' || SQLERRM || ' where nom_snapshot = '''|| nom_snapshot || '''';
END;
***************************************
et donc la proc2 est la suivante :
DECLARE
nom_snapshot varchar2(50);
cursor c1 is select b.nom_snapshot from user_snapshots a
begin
open c1;
loop
fetch c1 into nom_snapshot;
exit when c1%NOTFOUND;
MAPROC(nom_snapshot) ;
end loop;
close c1;
end;
/

la proc2 est en erreur, à moins d'y ajouter le pavé exception.

Pour simuler une erreur, je fais en sorte que l'étape "dbms_snapshot.refresh(nom_snapshot);" de la proc1 (MAPROC()) ne puisse pas s'exécuter correctement.

Des idées ?
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
23 janv. 2010 à 00:03
Bonsoir Gegecret,
De mémoire, il me semble qu'il te faut mettre un RAISE ou RAISE_APPLICATION_ERROR à la fin de ton WHEN OTHERS THEN afin que le traitement s'arrête. Si tu ne lui indiques pas de s'arrêter, comme tu as géré l'erreur, le traitement est correct donc peut continuer.

Petite remarque :
Intègre un format de date dans l'ordre SELECT :
    SELECT TO_CHAR(SYSDATE, tonFormatDeDate) INTO ladate FROM DUAL;

Ainsi, lorsque tu lances le rafraîchissement de ton snapshot, tu seras sûr du format de date à utiliser pour la variable ladate :
  execute immediate 'UPDATE update_snapshot set DATE_REFRESH = to_date('''
                                             || ladate || '', ''tonFormatDeDate'') where nom_snapshot = '''
                                             || nom_snapshot || '''';

où tonFormatDeDate peut valoir par exemple : DD/MM/YYYY HH24:MI

Remarque :
je pense que ton erreur (en tout cas, ça doit être une cause probable) est dûe au format que tu n'as pas précisé ;-)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Salut,

désolé pour le passage tardif.

pour ma part, plusieurs choses me chagrinent :
* pourquoi utiliser un execute immediate ? pourquoi ne pas simplement envoyer
UPDATE update_snapshot
SET DATE_REFRESH = sysdate
WHERE update_snapshot.nom_snapshot = nom_snapshot;

ou
UPDATE update_snapshot
SET ERREUR = SQLERRM
WHERE update_snapshot.nom_snapshot = nom_snapshot;

* lorsque MAPROC se termine, la transaction n'est pas forcément validée. Si une erreur est consignée dans update_snapshot, le commit ne surviendra qu'au prochain appel successful de MAPROC
* pourquoi utiliser ladate en varchar alors que tu ne manipules que des dates. Déclare plutot ladate en type date et passe-toi des conversions (même les implicites)
* et maintenant, le plus vicieux : comment se comporte ton échafaudage si l'erreur se produit dans l'update du bloc exception ? comment peux-tu affirmer qu'il ne s'y produit jamais une erreur ?
0