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 :

[Forms6i] Enchainement de triggers


Sujet :

Oracle

  1. #1
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut [Forms6i] Enchainement de triggers
    Bonjour !

    Voila j'ai un petit soucis de compréhension concernant l'enchainement des triggers.

    J'explique ma situation : ma forme contient 3 onglets, sur l'onglet qui me pose probleme, j'ai un bloc maitre et un bloc détail. Une regle de gestion impose qu'on ne puisse pas changer de ligne dans le bloc detail si la ligne n'est pas completement rempli (Ce test est effectué dans le trigger When-Validate-Record). Dans ce cas, un message d'erreur apparait.

    Mon probleme est le suivant : quand je remplis partiellement ma ligne de détail et que je decide de changer d'onglet pour provoquer l'erreur expliquee plus haut, mon message d'erreur apparait bien, mais 4 fois (alors que je ne pense passer dans W-V-R qu'une seule fois...). De plus ce message d'erreur apparait sur l'onglet que j'essaie d'atteindre alors que je pensais que le W-V-R allait survenir avant que je quitte mon onglet initial.

    Je pense donc avoir placé mon controle de pertinence des champs dans un mauvais trigger, qu'en pensez vous ?

    Merci pour votre aide !

  2. #2
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Quel est le code du trigger W-V-R ?

  3. #3
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par SheikYerbouti
    Quel est le code du trigger W-V-R ?
    Il contient un appel vers une procedure, tout simplement.

    Et cette procedure ressemble a ç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
    PROCEDURE PROC_PRESENCE IS
     
    BEGIN
     
    	--Tests sur présence valeurs.	
    	--*** UTILISATION
    	IF :BLK_T000.UTILISATION IS NULL THEN
    		AFFICHE_MESSAGE(Get_Error_Message('MSG_097'),'E');		
    	END IF;
    	--*** VOL
    	IF :BLK_T000.FLIGHT IS NULL THEN
    		AFFICHE_MESSAGE(Get_Error_Message('MSG_092'),'E');		
    	END IF;
    END;
    C'est tout...

  4. #4
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Dans la procedure il faut stopper le traitement avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Raise Form_Trigger_Failure ;
    et dans le trigger W-V-R trapper l'exception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Begin
      -- Appel de la procedure
    Exception
      When Form_Trigger_Failure Then
         Raise ;
    End ;

  5. #5
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par SheikYerbouti
    Dans la procedure il faut stopper le traitement avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Raise Form_Trigger_Failure ;
    c'est ce que fait la procedure AFFICHE_MESSAGE();
    En fonction du 2e parametre, on cree un message d'erreur ou d'information en enchainant les commandes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    al_id := FIND_ALERT('ALERT_ERROR'); 
    SET_ALERT_PROPERTY(al_id,ALERT_MESSAGE_TEXT,P_LIBELLE);
    al_button := SHOW_ALERT(al_id);
    RAISE FORM_TRIGGER_FAILURE;
    Citation Envoyé par SheikYerbouti
    et dans le trigger W-V-R trapper l'exception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Begin
      -- Appel de la procedure
    Exception
      When Form_Trigger_Failure Then
         Raise ;
    End ;
    c'est déjà fait (excuse j'aurais du le préciser...)

  6. #6
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Ajoutez-le quand même dans PROC_PRESENCE.

  7. #7
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par SheikYerbouti
    Ajoutez-le quand même dans PROC_PRESENCE.
    Bon je le fais parce que c'est SheikYerbouti qui me le demande

  8. #8
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut
    Bon, ca n'a rien changé.
    Mon message d'erreur apparait toujours 4 fois quand je veux passer à un autre onglet...

  9. #9
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Bon, et bien il va falloir exécuter la forme en mode debug. (placer le point d'arrêt sur la première instruction du W-V-R).

  10. #10
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Essaie de valider ton enregistrement avant de changer de page, en faisant par exemple dans le trigger WHEN-TAB-PAGE-CHANGED (au début du trigger) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if :system.tab_previous_page = 'ONGLET_DETAIL' then
       set_canvas_property ('CANVAS_ONGLET', topmost_tab_page, 'ONGLET_DETAIL');
    	 go_block ('BLOC_DETAIL');
       if not form_success then
          raise form_trigger_failure;
       end if;   
    end if;
    Sinon repère, les go_block ou go_item que tu peux faire (y compris dans les triggers de relation maître détail).

  11. #11
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut
    Bon, j'ai mené ma petite enquete a ce sujet.

    Tout d'abord, l'idée du trigger WHEN-TAB-PAGE-CHANGED est écartée, celui-ci est appelé apres WHEN-VALIDATE-RECORD.
    Les GO_BLOCK et GO_ITEM, c'est bien simple, il n'y en a pas.

    Donc je suis passé en mode débug.
    Pour mémoire, voila à quoi ressemble mon code :

    WHEN-VALIDATE-RECORD :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    BEGIN
     
    	-- Contrôle presence des champs.
    	PROC_PRESENCE;
     
    EXCEPTION
    WHEN PACK_CONST.ERR_FORMS THEN
    	--SI Erreur NON-ORACLE => Forms.
    	RAISE FORM_TRIGGER_FAILURE;
    WHEN OTHERS THEN
    	--SINON: Erreur ORACLE.
    	AFFICHE_MESSAGE('Erreur ORACLE: (' || SQLCODE|| ') - '||SQLERRM,'E');	
     
    END;
    PROC_PRESENCE (vérifie la presence de champs obligatoires) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    PROCEDURE PROC_PRESENCE IS
     
    BEGIN
     
       --Tests sur présence valeurs.   
       --*** UTILISATION
       IF :BLK_T000.UTILISATION IS NULL THEN
          AFFICHE_MESSAGE(Get_Error_Message('MSG_097'),'E');      
       END IF;
       --*** VOL
       IF :BLK_T000.FLIGHT IS NULL THEN
          AFFICHE_MESSAGE(Get_Error_Message('MSG_092'),'E');      
       END IF;
    END;
    et enfin AFFICHE_MESSAGE (génère un message d'erreur, d'avertissement ou d'information suivant le parametre passé) :
    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
    PROCEDURE AFFICHE_MESSAGE(P_LIBELLE VARCHAR2, P_NIVEAU_ALERTE VARCHAR2) IS
    		al_id     	Alert; 
    		al_button 	Number;
    BEGIN
     
    	-- traitement d'une erreur
      	IF P_NIVEAU_ALERTE = 'E' THEN
      		al_id := FIND_ALERT('ALERT_ERROR'); 
      		SET_ALERT_PROPERTY(al_id,ALERT_MESSAGE_TEXT,P_LIBELLE);  			
      		al_button := SHOW_ALERT(al_id);
     
    		RAISE FORM_TRIGGER_FAILURE;
     
    	-- traitement d'un avertissement
      	ELSIF P_NIVEAU_ALERTE = 'W' THEN
     
      		al_id := FIND_ALERT('ALERT_AVERTISSEMENT'); 
      		SET_ALERT_PROPERTY(al_id,ALERT_MESSAGE_TEXT,P_LIBELLE);  			
      		al_button := SHOW_ALERT(al_id);
     
    		IF al_button <> ALERT_BUTTON1 THEN
    			RAISE FORM_TRIGGER_FAILURE;
    		END IF;  		
     
    	-- Information
    	ELSIF P_NIVEAU_ALERTE = 'I' THEN
      		al_id := FIND_ALERT('ALERT_INFORMATION'); 
      		SET_ALERT_PROPERTY(al_id,ALERT_MESSAGE_TEXT,P_LIBELLE);  			
      		al_button := SHOW_ALERT(al_id);		
     
    	ELSE
    		NULL;
      	END IF;
     
    END;
    Apres de multiples mises en commentaire, j'ai pu constater que la repetition du message d'erreur ne se produit que lorsque
    Or la seule difference avec les autres elements du IF est la présence d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RAISE FORM_TRIGGER_FAILURE
    Et mon probleme c'est que je ne vois pas en quoi cette commande, à elle seule, me fait repartir au début du W-V-R, pour finalement boucler 4 fois...
    Une idée ?

  12. #12
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    PROC_PRESENCE ne traite pas l'exception Form_Trigger_Failure ni W-V-R

  13. #13
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par SheikYerbouti
    PROC_PRESENCE ne traite pas l'exception Form_Trigger_Failure ni W-V-R
    bah je pense la traiter pourtant (du moins dans W-V-R)
    En effet mon premier bloc exception est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    WHEN PACK_CONST.ERR_FORMS THEN
       --SI Erreur NON-ORACLE => Forms.
       RAISE FORM_TRIGGER_FAILURE;
    Or ERR_FORMS est défini de la maniere suivante dans le package PACK_CONST :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ERR_FORMS 	exception;
    pragma 	exception_init(ERR_FORMS, -100501);
    Cela n'est pas satisfaisant ?

  14. #14
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Pour faire simple, au début, testez dans chaque couche de la pile les variables Form_trigger_failure et Form_Success.

  15. #15
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par SheikYerbouti
    Pour faire simple, au début, testez dans chaque couche de la pile les variables Form_trigger_failure et Form_Success.
    Je reproduis mon problème dans avec un montage plus simplifié :
    Il suffit que W-V-R soit de la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    BEGIN
     
    	AFFICHE_MESSAGE('ERROR !','E');
     
    EXCEPTION
    WHEN PACK_CONST.ERR_FORMS OR Form_Trigger_Failure THEN
    	--SI Erreur NON-ORACLE => Forms.
    	RAISE FORM_TRIGGER_FAILURE;
    WHEN OTHERS THEN
    	--SINON: Erreur ORACLE.
    	AFFICHE_MESSAGE('Erreur ORACLE: (' || SQLCODE|| ') - '||SQLERRM,'E');	
     
    END;
    Au niveau debug, on voit qu'on entre bien dans AFFICHE_MESSAGE, le message "ERROR !" s'affiche puis on arrive sur la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RAISE FORM_TRIGGER_FAILURE;
    (toujours dans AFFICHE_MESSAGE).

    Puis a l'etape suivante je suis dans le bloc Exception de W-V-R, au niveau du RAISE FORM_TRIGGER_FAILURE;

    A l'etape suivante, je me retrouve a nouveau au début du trigger W-V-R...

  16. #16
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    1. La question que je me pose : puisque cela fonctionne quand tu changes de ligne de détail, que fais-tu en plus quand tu changes d'onglet ?

    2. Il ne faut pas seulement regarder au premier déclenchement du WVR, mais trouver si qui le déclenche les fois suivantes (=> ne fais tu pas de go_block (ou go_item) dans ton when-tab-page-changed ?, ou dans un trigger when-new-block-instance).

    3. Il est normal que lorque tu ne fais pas raise form_trigger_failure, ton message ne se déclenche qu'une fois : ton enregistrement étant validé, forms ne cherche pas à le valider une 2è fois

  17. #17
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par plaineR
    1. La question que je me pose : puisque cela fonctionne quand tu changes de ligne de détail, que fais-tu en plus quand tu changes d'onglet ?
    Très bonne remarque, j'avais oublié que le comportement n'etait pas identique quand je changais de ligne détail...
    Eh bien malheureusement, ca ne fait pas bcp avancer le schmilblik : quand je débug (en placant un breakpoint au début de W-V-R), le comportement est le meme sauf qu'une arrivé dans le bloc exception de W-V-R, je sors "normalement" du trigger. Le message d'erreur est donc affiché une fois seulement...

    Citation Envoyé par plaineR
    2. Il ne faut pas seulement regarder au premier déclenchement du WVR, mais trouver si qui le déclenche les fois suivantes (=> ne fais tu pas de go_block (ou go_item) dans ton when-tab-page-changed ?, ou dans un trigger when-new-block-instance).
    Dans when-tab-page-changed il y a bien des go_block, je vais regarder cela...

    Citation Envoyé par plaineR
    3. Il est normal que lorque tu ne fais pas raise form_trigger_failure, ton message ne se déclenche qu'une fois : ton enregistrement étant validé, forms ne cherche pas à le valider une 2è fois
    ok c'est noté !

  18. #18
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Citation Envoyé par lafouine
    Eh bien malheureusement, ca ne fait pas bcp avancer le schmilblik : quand je débug (en placant un breakpoint au début de W-V-R), le comportement est le meme sauf qu'une arrivé dans le bloc exception de W-V-R, je sors "normalement" du trigger. Le message d'erreur est donc affiché une fois seulement...
    J'ai une confiance très limitée dans le debugger de forms 6i

    Mets plutôt des messages du style (pour pouvoir les supprimer facilement) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    message ('DEBUG NOM_DU_TRIGGER NOM_DU_BLOCK');pause;
    dans les triggers qui peuvent se déclencher :
    - WHEN-VALIDATE_RECORD
    - WHEN-NEW-BLOCK-INSTANCE
    - WHEN-TAB-PAGE-CHANGED
    - et tous les endroits où tu as des go_item et des go_block (enfin dans un premier temps ceux que tu pensent être concernés )

  19. #19
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par plaineR
    J'ai une confiance très limitée dans le debugger de forms 6i
    et tu fais bien !
    Alors que dans le debugger je passais dans WHEN-TAB-PAGE-CHANGED apres être passé dans WHEN-VALIDATE-RECORD, lors de l'exécution il s'avère que le comportement est inverse !

    Or dans W-T-P-G il y avait des GO_BLOCK, ce qui avait pour consequence de me declencher W-V-R...

    Du coup je pense que je vais reussir a m'en sortir !

    Merci bcp
    (je clos le thread qd je suis vraiment certain que ca marche )

  20. #20
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 119
    Points : 74
    Points
    74
    Par défaut
    Bon alors où en sommes nous ? Le probleme n'existe plus quand on essaie de changer de thread, ce qui est une bonne chose.

    Le soucis est que maintenant mon probleme survient quand j'essaie de créer une nouvelle ligne (à l'aide de la souris) dans mon bloc détail.
    La chronologie de l'erreur est similaire a celle exposé précédemment :
    1/ je crée une ligne incomplete et donc erronée dans mon bloc detail (ie un des champs de mon bloc detail n'est pas renseigné)
    2/ je clique sur la ligne suivante pour générer une erreur. Le trigger When-new-record-instance se déclenche
    3/ on passe ensuite par le trigger when-validate-record (toujours le meme code que plus haut dans le thread). Dans ce trigger on entre dans la proc PROC_PRESENCE qui lève une erreur a l'aide de la procedure AFFICHE_MESSAGE
    4/ l'affichage du message d'erreur se fait, on passe ensuite dans le bloc exception de W-V-R
    5/ on sort du trigger exception pour se retrouver a nouveau en début de W-V-R. On affiche donc deux fois le message d'erreur et en plus la ligne est quand meme crée malgré le message d'erreur...

    Alors vous allez me dire que je suis lent à la détente mais honnetement je ne comprends pas ce qui explique cette répétition... je me doute qu'il y a une histoire de propagation d'exception là dessous mais ce qui est sur c'est que je ne la comprends pas...

Discussions similaires

  1. Problème sur "enchainement" de triggers
    Par skoud dans le forum Requêtes
    Réponses: 0
    Dernier message: 30/04/2015, 17h25
  2. Problème enchainement création trigger
    Par mafanta dans le forum SQL
    Réponses: 2
    Dernier message: 18/06/2012, 15h38
  3. Réponses: 4
    Dernier message: 31/10/2006, 18h13
  4. [Forms6i] Touche Entrée et trigger KEY-ENTER
    Par lafouine dans le forum Forms
    Réponses: 4
    Dernier message: 12/09/2005, 19h42
  5. [Comparatif] Procédures stockées, triggers, etc.
    Par MCZz dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 28/08/2002, 13h27

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