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 13/04/2007, 23h35   #1
jux
Candidat au titre de Membre du Club
 
Inscription : juillet 2002
Messages : 23
Détails du profil
Informations forums :
Inscription : juillet 2002
Messages : 23
Points : 11
Points : 11
Par défaut curseur dans un trigger

Bonjour,
j'ai créé mon premier trigger avec un curseur à l'intérieur :
la partie du code qui pose problème est en rouge.
L'exécution du code suivant donne les messages d'erreur suivants :

LINE/COL ERROR
27/1 PL/SQL: Statement ignored
27/28 PLS-00405: sous-interrogation non autorisée dans ce contexte
31/1 PL/SQL: Statement ignored
31/23 PLS-00405: sous-interrogation non autorisée dans ce contexte
39/1 PL/SQL: Statement ignored
39/24 PLS-00405: sous-interrogation non autorisée dans ce contexte

/* mon trigger :*/
create or replace trigger trigger_inscription
before update or insert on inscription
for each row
declare
nbre_etud number(2,0);
nbre_module number(2,0);
cursor curseur_prerequis is select codmodpreq from prerequis start with codmod = :new.codmod connect by prior codmodpreq=codmod;
codmod_du_curseur prerequis.codmod%type;
begin
/*Test si les modules prerequis sont présents dans la table inscription : */
open curseur_prerequis;
loop
fetch curseur_prerequis into codmod_du_curseur;
exit when curseur_prerequis%notfound;

if codmod_du_curseur not in(select codmod from inscription where numetud=:new.numetud)
then raise_application_error ( -20003,'Erreur cet étudiant ne s est pas inscrit dans un(ou les) module(s) prerequis');
end if;

if :new.numetud not in(
select e.numetud from etudiant e
where not exists(select ex.codmod from examen ex where ex.codmod=codmod_du_curseur and not exists(
select r.numetud,r.codexam from resultat r,module m where e.numetud=r.numetud
and ex.codexam=r.codexam)))
then raise_application_error ( -20004,'Erreur cet étudiant n a pas passé tous les examens dans un des modules prerequis');
end if;

if :new.numetud not in (select num_etudiant from vue_trigger3 where code_module=codmod_du_curseur)
then raise_application_error ( -20005,'Erreur cet étudiant n a pas la moyenne (noteprerequis) dans un des modules prerequis');
end if;

end loop;
close curseur_prerequis;
end;
/

C'EST AU NIVEAU DES 3 IF DANS LE CURSEUR QUE CA COINCE.
JE NE SAIS PAS SI CE TYPE DE REQUETE EST AUTORISEE ICI.
MERCI DE VOTRE AIDE D'AVANCE
jux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/04/2007, 00h57   #2
Rédacteur
 
Homme Salim
Développeur et DBA Oracle
Inscription : octobre 2006
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Salim
Localisation : Canada

Informations professionnelles :
Activité : Développeur et DBA Oracle

Informations forums :
Inscription : octobre 2006
Messages : 872
Points : 1 100
Points : 1 100
Salut,

Première remarque dans un block plsql le select a la synthaxe suivante
NB : On utilise le select dans un block plsql s'il ramene une seule ligne( si le nombre de ligne est >1 alors tu auras l'erreur too_many_rows et s'il ramene aucune ligne tu auras l'erreur no_data_found)

De préférence utiliser le curseur pour ne pas gérer les erreurs
Code :
1
2
3
4
5
Select champs1,champs2...
into p1,p2...
from table ....
where ...
Tu peux utiliser le code ci-dessous
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
declare 
.......
nb_codmod  number(2,0); 
begin 
............
SELECT  count(codmod) 
INTO  nb_codmod 
FROM inscription 
WHERE numetud=:new.numetud AND codmod=codmod_du_curseur ;
IF nb_codmod =0 then 
 raise_application_error ( -20003,'Erreur cet étudiant ne s est pas inscrit dans un(ou les) module(s) prerequis');
end IF;
A la place du code suivant
Code :
1
2
3
4
 
IF codmod_du_curseur NOT IN(SELECT codmod FROM inscription WHERE numetud=:new.numetud)
then raise_application_error ( -20003,'Erreur cet étudiant ne s est pas inscrit dans un(ou les) module(s) prerequis');
end IF;
salim11 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2007, 01h30   #3
jux
Candidat au titre de Membre du Club
 
Inscription : juillet 2002
Messages : 23
Détails du profil
Informations forums :
Inscription : juillet 2002
Messages : 23
Points : 11
Points : 11
super merci pour le coup de main : j'ai mis des count() partout et ça marche.
jux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2007, 17h44   #4
Rédacteur
 
Homme Salim
Développeur et DBA Oracle
Inscription : octobre 2006
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Salim
Localisation : Canada

Informations professionnelles :
Activité : Développeur et DBA Oracle

Informations forums :
Inscription : octobre 2006
Messages : 872
Points : 1 100
Points : 1 100
Salut,

De rien, n'oublie pas de mettre la discussion a résolu.
salim11 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2007, 17h52   #5
Expert Confirmé
 
Avatar de LeoAnderson
 
Inscription : septembre 2004
Messages : 2 942
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 2 942
Points : 2 972
Points : 2 972
NON ! c'est catastrophique pour les perfs !!!
(et ne me dites pas qu'on s'en fout, en ne s'en fout jamais des perfs, et il faut prendre les bonnes habitudes dès le départ !)

Si le but est de savoir s'il a ou non des modules, au lieu de tout compter (et potentiellement parcourir des millions de lignes) et juste comparer avec 0 ou 1, il faut travailler par gestion des exceptions !

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
BEGIN
...
   BEGIN
      SELECT  codmod
        INTO ln$codmod 
        FROM inscription 
       WHERE numetud=:new.numetud AND codmod=codmod_du_curseur ;
   EXCEPTIONS
      WHEN NO_DATA_FOUND THEN
         -- C'est qu'il n'a aucune inscription
      WHEN TOO_MANY_ROWS THEN
         -- C'est qu'il a plusieurs inscriptions (2 ? 1000 ? 1 milliard ? peu importe)
   END;
...
END;
LeoAnderson est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2007, 18h11   #6
Rédacteur
 
Homme Salim
Développeur et DBA Oracle
Inscription : octobre 2006
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Salim
Localisation : Canada

Informations professionnelles :
Activité : Développeur et DBA Oracle

Informations forums :
Inscription : octobre 2006
Messages : 872
Points : 1 100
Points : 1 100
Salut,

Merci pour ta remarque Leo, C'est bien d'apprendre les bonnes manières et ne jamais négliger la performance.
salim11 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h34.


 
 
 
 
Partenaires

Hébergement Web