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 18/05/2007, 22h01   #1
Futur Membre du Club
 
Homme Baptiste
Développeur .NET
Inscription : janvier 2005
Messages : 64
Détails du profil
Informations personnelles :
Nom : Homme Baptiste
Âge : 27
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur .NET
Secteur : Finance

Informations forums :
Inscription : janvier 2005
Messages : 64
Points : 16
Points : 16
Par défaut Problème de Trigger inter-table

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE OR REPLACE TRIGGER trigger_prix_activite
BEFORE INSERT ON Activite
FOR EACH ROW
 
DECLARE
LN$Num Station.tarif%Type ;
 
BEGIN
	SELECT tarif INTO LN$Num FROM Station
	WHERE Station.nomStation = :NEW.nomStation;
	IF (:NEW.prix >= LN$Num) THEN
		raise_application_error(-20000,'Erreur trigger prix_activite');
	END IF;
END;
/
Réponse de Oracle
Code :
1
2
3
4
5
6
7
SQL> INSERT INTO Activite VALUES('Marbela', 'Musee de la France', 3000);
INSERT INTO Activite VALUES('Marbela', 'Musee de la France', 3000)
     *
ERREUR Ó la ligne 1 :
ORA-20000: Erreur TRIGGER prix_activite
ORA-06512: Ó "BAPTX.TRIGGER_PRIX_ACTIVITE", ligne 8
ORA-04088: erreur lors d'exÚcution du dÚclencheur 'BAPTX.TRIGGER_PRIX_ACTIVITE'
Donc en théorie il lève bien l'exception quand j'essaye de rentrer le prix d'une activité supérieur au tarif d'un séjour. Néanmoins, je ne suis pas sure que les trois lignes suivantes doivent apparaitre. Et en gros visiblement il me montre une belle grosse erreur. Mais disons que sqlplus est pas doué pour pointer du doigt précisément une erreur et comme on débute seulement les triggers en cours... Et pourtant ce code est déjà inspiré du net

Si vous pouvez m'aider... Merci
baptx est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2007, 22h25   #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
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
SQL> edit
écrit file afiedt.buf
 
  1  declare
  2  v number ;
  3  begin
  4  v:=5;
  5  IF v =5 then
  6    raise_application_error(-20000,'Nombre est egal a 5');
  7  end IF;
  8* end ;
SQL> /
declare
*
ERREUR à la ligne 1 :
ORA-20000: Nombre est egal a 5
ORA-06512: à ligne 6
regarde ça
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
 
4/ LES EXCEPTIONS UTILISATEUR ANONYMES
•	Ces exceptions sont définies et déclenchées explicitement  par le 
programmeur. 
•	PL/SQL met à la disposition des programmeurs des codes 
d’exceptions allant      de   -20 000 à –20 999 .
•	Le programmeurs devra associer un message d’erreur à un code
 inclus dans cette plage.
•	L'exception est alors déclenchée avec l'ordre 
RAISE_APPLICATION_ERROR.
•	Cette procédure sert à améliorer la  communication entre le client 
et le serveur ORACLE en proposant des messages personnalisés . 
Exemple : 
EXCEPTIONS UTILISATEUR ANONYMES
 
 
BEGIN
-- codes réservés de –20000 à -20999
 IF  cond  then 
     raise_application_error 
          (-20 045 . ‘message cond’) ….
 
 
EXCEPTION
-- On remplace le message Oracle
   When no_data_found then 
         Raise_application_error
            (-20 001 ,  ‘pas de données’) ;
salim11 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/05/2007, 12h33   #3
Futur Membre du Club
 
Homme Baptiste
Développeur .NET
Inscription : janvier 2005
Messages : 64
Détails du profil
Informations personnelles :
Nom : Homme Baptiste
Âge : 27
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur .NET
Secteur : Finance

Informations forums :
Inscription : janvier 2005
Messages : 64
Points : 16
Points : 16
Donc si je comprend bien, Oracle lève deux exceptions. L'une qu'on récupère avec notre code personnalisé, et l'autre qu'Oracle lui-même lève, il faut donc la catcher aussi.

Je vais essayer de rajouter une zone Exception dans le code. Mais est-ce tout de même normal que Oracle ne lève pas uniquement mon exception personnalisée de code -20000 ?
baptx est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/05/2007, 12h46   #4
Futur Membre du Club
 
Homme Baptiste
Développeur .NET
Inscription : janvier 2005
Messages : 64
Détails du profil
Informations personnelles :
Nom : Homme Baptiste
Âge : 27
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur .NET
Secteur : Finance

Informations forums :
Inscription : janvier 2005
Messages : 64
Points : 16
Points : 16
Bon bah visiblement d'après un tuto que j'ai trouvé sur developpez.com, quand le trigger fonctionne (donc empêche l'insertion), Oracle répond systématiquement:
- Code Personnalisé
- ORA-06512
- ORA-04088

Donc quelque part cela veut dire que mon trigger fonctionne. Mais du coup ce n'est pas du tout comme le C++/Java (je suis issu de ces langages) où quand on veut lever une exception, on lève que la personnalisée et pas les deux autres.

Donc je marque comme résolu mais est-il possible d'empêcher l'affichage des deux derniers messages d'erreurs ?
baptx est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/05/2007, 13h20   #5
Futur Membre du Club
 
Homme Baptiste
Développeur .NET
Inscription : janvier 2005
Messages : 64
Détails du profil
Informations personnelles :
Nom : Homme Baptiste
Âge : 27
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur .NET
Secteur : Finance

Informations forums :
Inscription : janvier 2005
Messages : 64
Points : 16
Points : 16
Par contre j'ai un problème dans un autre trigger, et franchement j'ai vraiment du mal avec la syntaxe SQL et les messages d'erreurs pas clairs que me renvoie Oracle. Mais c'est en faisant des erreurs qu'on apprend non ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CREATE OR REPLACE TRIGGER trigger_capacite_place
BEFORE INSERT ON Sejour
FOR EACH ROW
 
DECLARE
LN$Num Station.capacite%Type;
LN$Num2 Sejour.nbPlaces%Type;
 
BEGIN
	SELECT capacite INTO LN$Num FROM Station
	WHERE Station.nomStation = :NEW.station;
	SELECT sum(nbPlaces) INTO LN$Num2 FROM Sejour
	WHERE Sejour.nomStation= :NEW.station AND Sejour.debut= :NEW.debut;
	LN$Num2=LN$Num2 + :NEW.nbPlaces;
	IF (LN$Num2 >= LN$Num) THEN
		raise_application_error(-20000,'Pas assez de places !');
	END IF;
 
EXCEPTION
	When no_data_found then 
		Raise_application_error(-20001, 'Station non-trouvée');
END;
/
Le principe est d'aller interroger la table station pour récupérer la capacité totale de la station dans laquelle on veut réserver. Ensuite on va récupérer la somme de toutes les places reservées de la table Sejour pour la station donnée et la date de début de séjour. On ajoute à la somme le nombre de places que l'on veut reserver. Si le nombre total de places réservées est supérieur à la capacité totale, alors on lève une exception.

Mais Oracle me dit qu'il y a une erreur de syntaxe:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SQL> @BD\270_trigger_capacite_place;
 
Avertissement : DÚclencheur crÚÚ avec erreurs de compilation.
 
SQL> SHOW errors
Erreurs pour TRIGGER TRIGGER_CAPACITE_PLACE :
 
LINE/COL ERROR
-------- -----------------------------------------------------------------
10/9     PLS-00103: Symbole "=" rencontrÚ Ó la place d'un des symboles
         suivants :
         := . ( @ % ;
 
11/2     PLS-00103: Symbole "IF" rencontrÚ
Je pense que cela vient de la ligne où j'ajoute à ma variable LN$NUM2 le nombre de places de la ligne qu'on veut insérer. Pourtant, je croyais qu'une affection se faisant comme en C ? Je continue à chercher la syntaxe de mon côté.

Merci.
baptx est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/05/2007, 14h09   #6
Futur Membre du Club
 
Homme Baptiste
Développeur .NET
Inscription : janvier 2005
Messages : 64
Détails du profil
Informations personnelles :
Nom : Homme Baptiste
Âge : 27
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur .NET
Secteur : Finance

Informations forums :
Inscription : janvier 2005
Messages : 64
Points : 16
Points : 16
C'est bien ce que je pensais. On peut pas faire d'affectation comme en C. Du coup j'ai résolu le problème en faisant la somme dans la comparaison:
Code :
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 TRIGGER trigger_capacite_place
BEFORE INSERT ON Sejour
FOR EACH ROW
 
DECLARE
LN$Num Station.capacite%Type;
LN$Num2 Sejour.nbPlaces%Type;
 
BEGIN
	SELECT capacite INTO LN$Num FROM Station
	WHERE Station.nomStation = :NEW.station;
	SELECT sum(nbPlaces) INTO LN$Num2 FROM Sejour
	WHERE Sejour.station= :NEW.station AND Sejour.debut= :NEW.debut;
	IF (LN$Num2+ :NEW.nbPlaces >= LN$Num) THEN
		raise_application_error(-20000,'Pas assez de places !');
	END IF;
 
EXCEPTION
	When no_data_found then 
		Raise_application_error(-20001, 'Station non-trouvée');
END;
/
baptx est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2007, 17h03   #7
Futur Membre du Club
 
Homme Baptiste
Développeur .NET
Inscription : janvier 2005
Messages : 64
Détails du profil
Informations personnelles :
Nom : Homme Baptiste
Âge : 27
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur .NET
Secteur : Finance

Informations forums :
Inscription : janvier 2005
Messages : 64
Points : 16
Points : 16
Je me permets de réouvrir ce topic car j'ai encore une erreur sur un trigger. Le langage SQL n'est vraiment pas facile.

Le but du trigger est de vérifier si le nouveau prix d'une activité est inférieur à l'ancien prix. Si c'est le cas, on ajoute la différence de l'ancien prix et du nouveau prix au prix de la Station.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
CREATE OR REPLACE TRIGGER trigger_activitebaisse
BEFORE UPDATE OF Prix ON Activite
REFERENCING OLD AS old_activite NEW AS new_activite
FOR EACH ROW
BEGIN
   IF (new_activite.Prix<old_activite.Prix) THEN
   	UPDATE Station
	SET Station.Tarif=(old_activite.Prix-new_activite.Prix)+Station.Tarif
	WHERE Station.NomStation=new_activite.NomStation;
   END IF;
END;
/
Voici les erreurs d'Oracle:
Code :
1
2
3
4
5
6
7
SQL> SHOW ERRORS;
Erreurs pour TRIGGER TRIGGER_ACTIVITEBAISSE :
 
LINE/COL ERROR
-------- -----------------------------------------------------------------
2/4      PL/SQL: Statement ignored
2/8      PLS-00201: l'identificateur 'NEW_ACTIVITE.PRIX' doit Ûtre dÚclarÚ
La syntaxe du REFERENCING OLD & NEW ne fonctionne peut-être pas avec Oracle, j'ai pris l'exemple du net.
baptx est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/05/2007, 17h19   #8
Futur Membre du Club
 
Homme Baptiste
Développeur .NET
Inscription : janvier 2005
Messages : 64
Détails du profil
Informations personnelles :
Nom : Homme Baptiste
Âge : 27
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur .NET
Secteur : Finance

Informations forums :
Inscription : janvier 2005
Messages : 64
Points : 16
Points : 16
Visiblement, c'était bien le REFERENCING qui posait problème.
La solution:

Code :
1
2
3
4
5
6
7
8
9
10
11
CREATE OR REPLACE TRIGGER trigger_activitebaisse
AFTER UPDATE OF Prix ON Activite
FOR EACH ROW
BEGIN
   	IF (:NEW.prix<:OLD.prix) THEN
   		UPDATE Station
		SET Station.Tarif=(:OLD.prix-:NEW.prix)+Station.Tarif
		WHERE Station.NomStation=:NEW.NomStation;
	END IF;
END;
/
baptx 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 02h47.


 
 
 
 
Partenaires

Hébergement Web