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

PL/SQL Oracle Discussion :

Problème de Trigger inter-table


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 65
    Par défaut Problème de Trigger inter-table
    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
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  2. #2
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    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
     
    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 : 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
     
    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’) ;

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 65
    Par défaut
    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 ?

  4. #4
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 65
    Par défaut
    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 ?

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 65
    Par défaut
    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 : 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
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 65
    Par défaut
    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 : 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 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;
    /

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de trigger et TRUNCATE TABLE
    Par medhan dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 06/12/2013, 02h10
  2. Problème de trigger : table is mutating
    Par awalter1 dans le forum SQL
    Réponses: 6
    Dernier message: 08/02/2013, 23h11
  3. Réponses: 1
    Dernier message: 08/07/2009, 09h37
  4. problème Trigger sur table unique
    Par speedev dans le forum SQL Procédural
    Réponses: 11
    Dernier message: 21/01/2009, 12h09
  5. Problème avec trigger (table INSERTED)
    Par ygrim dans le forum Développement
    Réponses: 1
    Dernier message: 20/04/2008, 21h00

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