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

Oracle Discussion :

Erreur de trigger


Sujet :

Oracle

  1. #1
    Membre du Club Avatar de Pandapi
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 38
    Points : 53
    Points
    53
    Par défaut Erreur de trigger
    Bonjour


    Voilà, j'ai un projet de BD à faire et je dois créer des triggers.

    Le problème c'est que j'ai une erreur et comme on ne les a pas beaucoup vue en cours... difficile de corriger.

    Donc si quelqu'un pouvait m'aider, je pense que c'est une erreur facilement visible pour un habitué (genre mauvaise déclaration ou au mauvais endroit).

    Voilà le code de mon trigger :

    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
    create or replace trigger Medecin1
     
    	after insert on Medecin
    	for each row
     
    	declare specialite_labo number;
    		specialite_service number;
     
    	begin
     
     
    	select specialiteService into specialite_labo from StructureInterne
    	where :new.codeLabo = codeStructure;
     
    	select specialiteService into specialite_service from StructureInterne
    	where :new.codeService = codeStructure;
     
    	if(NOT(specialite_labo IS NULL) and NOT(specialite_service IS NULL) and (specialite_labo <> specialite_service)) then
     
    		delete from Medecin where INSEEMedecin = :new.INSEEMedecin ;
     
    		raise_application_error(-20001,'Medecin ayant un Labo et un Service de specialites differentes');
     
    	end if;
    end Medecin1;
    /
    SHOW ERRORS

    Je pense que les NOT(machin IS NULL) peuvent sûrement être améliorés en machin NOT NULL, ou autre chose, mais pour le moment le fichier compile, c'est à l'éxecution que le trigger plante.

    Voilà le message d'erreur :
    ERREUR � la ligne 1 :
    ORA-01403: aucune donnnnnn�e trouv
    ORA-06512: � "MABASE.MEDECIN1", ligne 7
    ORA-04088: erreur lors d'exxxxx�cution du ddddd�clencheur 'MABASE.MEDECIN1'

    Voilà, si quelqu'un pouvait m'aider à faire un trigger qui tourne comme il faut (même sans être optimisé, après je peux chercher tout seul), histoire de me débloquer ^^

    Merci d'avance.

  2. #2
    Membre chevronné Avatar de Garuda
    Homme Profil pro
    Chef de projet / Urbaniste SI
    Inscrit en
    Juin 2007
    Messages
    1 285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet / Urbaniste SI
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 285
    Points : 2 071
    Points
    2 071
    Par défaut
    Il faut gerer les exceptions
    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
    CREATE OR REPLACE TRIGGER Medecin1
     
        after INSERT ON Medecin
        FOR each row
     
        declare specialite_labo number;
            specialite_service number;
     
        begin
     
    BEGIN 
           SELECT specialiteService INTO specialite_labo FROM StructureInterne
       WHERE :new.codeLabo = codeStructure;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
         Null;
    END; 
    BEGIN
     SELECT specialiteService INTO specialite_service FROM StructureInterne
        WHERE :new.codeService = codeStructure;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
         Null;
    END; 
     
        IF(NOT(specialite_labo IS NULL) AND NOT(specialite_service IS NULL) AND (specialite_labo <> specialite_service)) then
     
            DELETE FROM Medecin WHERE INSEEMedecin = :new.INSEEMedecin ;
     
            raise_application_error(-20001,'Medecin ayant un Labo et un Service de specialites differentes');
     
        end IF;
    end Medecin1;
    /
    SHOW ERRORS
    Garuda गरूड
    Brahmâ la Guerre et Vishnu la Paix

    Oracle 12C R2 - Forms11GR2 - Toad 12 - sharePoint 2010

  3. #3
    McM
    McM est déconnecté
    Expert éminent

    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
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     DELETE FROM Medecin WHERE INSEEMedecin = :new.INSEEMedecin ;
            raise_application_error(-20001,'Medecin ayant un Labo et un Service de specialites differentes');
    Si tu fais un raise dans le trigger, les données sont rollbackées.
    Le delete ne sera donc pas effectué
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  4. #4
    Membre du Club Avatar de Pandapi
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 38
    Points : 53
    Points
    53
    Par défaut
    Merci de l'aide, le projet avance bien


    Par contre après avoir résolue ces erreurs là... on tombe sur un problème assez embêtant c'est que les prof ont dû oublier de relire le sujet, ils nous demandent d'empêcher des insertion ou des updates avec des triggers.

    Alors... nous on a essayé plusieurs solution, par exemple faire un update avec les anciennes valeurs si les valeurs de l'update ne sont pas bonnes, mais on se retrouve instantanément avec un problème de table en mutation...

    Ce qui est normal, mais je vois pas comment contourner le problème.

    Si le raise provoque un rollback, du coup ça pourrait être très utile, mais le raise nous sort une erreur, et si je me rappel bien mes cours, les rollback ne sont pas permis dans les triggers... je pensais donc que c'était dû à ça.

    L'erreur que nous sort le raise est :

    ERREUR � la ligne 1 :
    ORA-20001: Medecin ayant un Labo et un Service de specialites differentes
    ORA-06512: � "MABASE.SUIVI", ligne 11
    ORA-04088: erreur lors d'exxx�cution du ddd�clencheur 'MABASE.SUIVI'
    En testant avec autre chose qu'un raise, le trigger marche très bien...

    Donc si quelqu'un avait une idée du problème, je suis preneur.

    Merci d'avance

  5. #5
    McM
    McM est déconnecté
    Expert éminent

    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
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Si tu dois interdire l'insert et l'update, mieux vaut qu'il y ait une erreur.

    Sinon pour ton moyen de contournement pour l'update, tu ne devrais pas avoir de mutating table. Tu as du faire un select pour récupérer les anciennes valeurs : C'est pas bon !
    Tu as tout dans le trigger pour le faire (triger déclaré en BEFORE UPDATE FOR EACH ROW), toutes les colonnes préfixées de :old. te donnent les valeurs en base avant l'update.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  6. #6
    Membre du Club Avatar de Pandapi
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 38
    Points : 53
    Points
    53
    Par défaut
    Me revoilà


    Bon alors.... pour ce qui est du problème de mutation on ne peut pas toucher à la table qui a appelé le trigger, ça c'est reglé.


    Pour ce qui est du raise... j'ai demandé à une prof de BD et elle a également utilisé des raise pour les triggers donc c'est que ça doit être possible.

    Moi j'ai toujours la même erreur, elle m'a dit qu'elle utilisait des procédures appelées dans les triggers et qu'elle y faisait les raise, du coup je me suis dis que j'allais fais pareil, et bien non, oracle me jette toujours en disant que le trigger s'est mis à déconné...


    Je vous donne le code de mon trigger comme il est là :

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    create or replace procedure P1 as
     
    begin
     
    		raise_application_error (-20500,'Un médecin doit être dans un labo et un service de même spécialité');
     
    end P1;
    /
    SHOW ERRORS
     
     
    create or replace trigger Medecin1
     
    	before insert on Medecin
    	for each row
     
    	declare specialite_labo varchar2(20);
    		specialite_service varchar2(20);
    		unauthorized_insert EXCEPTION;
     
    	begin
     
     
    	if(NOT(:new.codeLabo IS NULL) and NOT(:new.codeService IS NULL)) then
     
    	select specialiteStructure into specialite_labo from StructureInterne
    	where :new.codeLabo = codeStructure;
     
    	select specialiteStructure into specialite_service from StructureInterne
    	where :new.codeService = codeStructure;
     
    	if(specialite_labo <> specialite_service) then
     
    		RAISE unauthorized_insert;
     
    	end if;
     
    	end if;
     
    	EXCEPTION
    		WHEN unauthorized_insert
    		THEN
    		P1;
     
     
    end Medecin1;
    /
    SHOW ERRORS

    C'est plutôt assez simple je vois pas trop pourquoi chez les autres le raise passe et chez moi il me provoque une erreur.

    Je met aussi le message d'erreur obtenue :

    INSERT INTO Medecin values (72812, 78940,'Gériatrie', 1,'S','L','GERIA-S','GERIA-L')
    *
    ERREUR � la ligne 1 :
    ORA-20500: Un médecin doit être dans un labo et un service de même
    spécialité
    ORA-06512: � "MABASE.P1", ligne 7
    ORA-06512: � "MABASE.MEDECIN1", ligne 27
    ORA-04088: erreur lors d'execution du declencheur 'MABASE.MEDECIN1'

    Vous pouvez voir qu'ici le message du raise passe avant que le trigger s'arrête c'est donc qu'il a bien lancé la procédure, tout se passe normalement... mais il y a une erreur d'execution du trigger.

    Après... peut être que le trigger doit bien planter je sais pas... le raise levant une erreur... mais le message me parait quand même sérieusement axé sur le fait que le trigger a une erreur.

    Puis je pense pas que le trigger doive planter, même si au final l'effet produit est celui voulu (ne pas enregistrer ou modifier dans la table), le fait que ça ne se fasse pas à cause du fait que le trigger plante c'est pas très propres, ça serait mieux si c'était lui qui l'empêchait.
    Et si moi je ne trouve pas le truc propre... j'ose même pas imaginé ce que les profs pourraient en penser


    Merci d'avance

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

Discussions similaires

  1. erreur sur trigger UPDATE
    Par izakiel dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 29/06/2009, 21h33
  2. Erreur 'SHOW TRIGGERS LIKE'
    Par Dikmas dans le forum MySQL
    Réponses: 5
    Dernier message: 22/12/2008, 11h29
  3. [SQL2000] Erreur sur Trigger
    Par tornade69 dans le forum Développement
    Réponses: 2
    Dernier message: 21/01/2008, 21h42
  4. Erreur de trigger
    Par Rakken dans le forum Administration
    Réponses: 3
    Dernier message: 30/11/2006, 11h35
  5. Erreur dans TRIGGER
    Par taroudant dans le forum SQL Procédural
    Réponses: 5
    Dernier message: 02/08/2006, 14h31

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