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 :

Problème avec trigger insert


Sujet :

Oracle

  1. #1
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Mai 2011
    Messages : 11
    Par défaut Problème avec trigger insert
    bonjour,
    je veux faire un trigger qui bloque l'insertion dans une table pour certaine valeurs, et faire l'insertion dans une autre table. merci bcp

  2. #2
    Membre très actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2011
    Messages : 146
    Par défaut
    Bonjour,

    Qu'as tu déjà essayé ?

  3. #3
    Membre extrêmement actif
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Billets dans le blog
    6
    Par défaut
    quelle sont tes initiatives.

  4. #4
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Mai 2011
    Messages : 11
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    CREATE OR REPLACE TRIGGER AR.RA_INTERFACE_AFTER_INSERT
    BEFORE INSERT
        ON RA_INTERFACE_LINES_ALL REFERENCING NEW AS New OLD AS Old
        FOR EACH ROW
    DECLARE   
     
        v_type varchar2(10);
        exception_1 exception;
     
    BEGIN
     
    select distinct ractta.type into v_type
      from ar.ra_batch_sources_all rbsa,ar.ra_cust_trx_types_all ractta
      where rbsa.name = :NEW.batch_source_name
      and ractta.cust_trx_type_id = :NEW.cust_trx_type_id
      and rbsa.org_id = :NEW.org_id;
     
      if ( :NEW.org_id=158 and :NEW.INTERFACE_LINE_ATTRIBUTE4='0' and :NEW.INTERFACE_LINE_CONTEXT='ORDER ENTRY' and v_type='INV') then
     
       INSERT INTO RANDA.SMT_RA_INTERFACE_LINES_ALL 
      (LINE_ID, ... )
            VALUES
      (:NEW.LINE_ID, ... );
     
       raise exception_1;
       end if;
     
        EXCEPTION
         WHEN exception_1 THEN RAISE;
    END RA_INTERFACE_AFTER_INSERT;
    /

  5. #5
    Membre extrêmement actif
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Billets dans le blog
    6
    Par défaut
    je ne voix pas le probleme

  6. #6
    Membre très actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2011
    Messages : 146
    Par défaut
    Bonjour,

    Je pense qu'il va te falloir 2 triggers + 1 collection pour gerer ce cas.

    1) Creer une collection publique destinée à stocker les pk de la table RA_INTERFACE_LINES_ALL REFERENCING.

    2) Créer un trigger sur before insert sur la table RA_INTERFACE_LINES_ALL REFERENCING.
    Si tes conditions sont remplies, alimente la table SMT_RA_INTERFACE_LINES_ALL
    et
    alimente la collection avec de quoi identifier la ligne inserée sur RA_INTERFACE_LINES_ALL

    3) creer un deuxieme trigger sur la table SMT_RA_INTERFACE_LINES_ALL
    sur after insert
    Recupere la collection alimentée par le premier trigger et drop les lignes de la table RA_INTERFACE_LINES_ALL

    4) detruit la collection avec un .DELETE en fin de processus.

  7. #7
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Mai 2011
    Messages : 11
    Par défaut
    Citation Envoyé par boussafi Voir le message
    je ne voix pas le probleme
    le problème c'est que dans le cas où la condition if est validé et le trigger goto exception_1 il ne commit pas l'insertion à l'autre table (RANDA.SMT_RA_INTERFACE_LINES_ALL) et on ne peut pas faire commit dans un trigger.

  8. #8
    Membre extrêmement actif
    Avatar de islamov2000
    Homme Profil pro
    Ingénieur d'études & developpement en informatique
    Inscrit en
    Septembre 2007
    Messages
    814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur d'études & developpement en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2007
    Messages : 814
    Billets dans le blog
    6
    Par défaut
    le commit dans le trigger est permis.
    ton trigger me semble correcte.
    teste..
    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
    CREATE OR REPLACE TRIGGER AR.RA_INTERFACE_AFTER_INSERT
    BEFORE INSERT
        ON RA_INTERFACE_LINES_ALL REFERENCING NEW AS New OLD AS Old
        FOR EACH ROW
    DECLARE   
     
        v_type varchar2(10);
        exception_1 exception;
     
    BEGIN
     
    SELECT DISTINCT ractta.type INTO v_type
      FROM ar.ra_batch_sources_all rbsa,ar.ra_cust_trx_types_all ractta
      WHERE rbsa.name = :NEW.batch_source_name
      AND ractta.cust_trx_type_id = :NEW.cust_trx_type_id
      AND rbsa.org_id = :NEW.org_id;
     
      IF ( :NEW.org_id=158 AND :NEW.INTERFACE_LINE_ATTRIBUTE4='0' AND :NEW.INTERFACE_LINE_CONTEXT='ORDER ENTRY' AND v_type='INV') then
     
       INSERT INTO RANDA.SMT_RA_INTERFACE_LINES_ALL 
      (LINE_ID, ... )
            VALUES
      (:NEW.LINE_ID, ... );
     
    commit;--ajouté
       end IF;
     
        EXCEPTION
         WHEN others THEN RAISE;--modifié
    END RA_INTERFACE_AFTER_INSERT;
    /

  9. #9
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 954
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 954
    Par défaut
    Citation Envoyé par ORA-007 Voir le message
    1) Creer une collection publique destinée à stocker les pk de la table RA_INTERFACE_LINES_ALL REFERENCING.
    Attention à la collection :Coding Triggers
    BEFORE Triggers Fired Multiple Times

    If an UPDATE or DELETE statement detects a conflict with a concurrent UPDATE, then Oracle Database performs a transparent ROLLBACK to SAVEPOINT and restarts the update. This can occur many times before the statement completes successfully. Each time the statement is restarted, the BEFORE statement trigger is fired again. The rollback to savepoint does not undo changes to any package variables referenced in the trigger. Your package should include a counter variable to detect this situation.
    En plus bonjour la concurrence d'accès avec une collection publique.


    Peut être que passer par une VUE et un TRIGGER INSTEAD OF permettrait de résoudre le problème.

    Sinon le plus simple est de faire une procédure stocké qui s'occupe de l'insert et de ne jamais faire d'insertion directement sur la table, mais toujours exécuter la procédure, comme ça pas besoin de trigger

    Citation Envoyé par boussafi Voir le message
    le commit dans le trigger est permis.
    Ben non !
    CREATE TRIGGER
    Restrictions on Trigger Implementation The implementation of a trigger is subject to the following restrictions:

    The PL/SQL block of a trigger cannot contain transaction control SQL statements (COMMIT, ROLLBACK, SAVEPOINT, and SET CONSTRAINT) if the block is executed within the same transaction.

  10. #10
    Membre très actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2011
    Messages : 146
    Par défaut
    En plus bonjour la concurrence d'accès avec une collection publique.
    solution déjà rencontrée chez un client en environnement multi user.

    La collection était déclarée dans un PKS.

  11. #11
    Membre Expert

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Par défaut
    Quelques soit la solution que l’on vous proposera ici, n’oubliez pas de la considérer d’un point de vue concurrentiel. Vous savez bien qu’en Oracle les selects (sans clause for update) ne bloquent pas les update/delete/insert et vice versa. Imaginez un instant que lors de l’exécution de votre trigger par un utilisateur user1, le select suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT DISTINCT ractta.type 
                  INTO v_type
      FROM ar.ra_batch_sources_all rbsa
          ,ar.ra_cust_trx_types_all ractta
      WHERE rbsa.name               = :NEW.batch_source_name
      AND   ractta.cust_trx_type_id = :NEW.cust_trx_type_id
      AND   rbsa.org_id             = :NEW.org_id;
    retourne bien un v_type = ‘INV’ ceci malgré le fait qu’un autre utilisateur, user2, l’ait déjà modifiée entre temps en lui attribuant une valeur ‘VNI’ mais sans atteindre la partie commit de son code. Le select exécuté par user1 va se rendre compte que la valeur a été modifiée mais pas encore ‘’commitée’’ et va donc utiliser les ‘’rollbacks segments ‘’ correspondants pour reconstruire l’image qu’avait le type au moment de l’exécution du select ci-dessous c'est-à-dire ‘INV’. Votre trigger va alors continuer et insérer dans la table

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SMT_RA_INTERFACE_LINES_ALL
    Mais manque de chance, le user2, juste après cet insert commit son travail et hop !!! vous avez quand même inséré une ligne dans la table SMT_RA_INTERFACE_LINES_ALL alors qu’il ne le fallait pas.
    D’une manière générale deux conseils sur les triggers:
    1. N’oubliez jamais de penser à l’aspect concurrentiel lors du développement d’un trigger
    2. Lorsque vous vous trouvez devant une logique qui vous semble compliquée à implémenter, il y a des chances dans ce cas que le trigger ne représente pas la place adéquate pour cette logique

  12. #12
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Mai 2011
    Messages : 11
    Par défaut
    Citation Envoyé par boussafi Voir le message
    le commit dans le trigger est permis.
    ton trigger me semble correcte.
    teste..
    non la commit ne marche pas le système affiche un problème pour commit

  13. #13
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Mai 2011
    Messages : 11
    Par défaut
    Citation Envoyé par ORA-007 Voir le message
    Je pense qu'il va te falloir 2 triggers + 1 collection pour gerer ce cas.
    merci j'ai essayé cette méthode mais ça marche pas

Discussions similaires

  1. Problème avec trigger (table INSERTED)
    Par ygrim dans le forum Développement
    Réponses: 1
    Dernier message: 20/04/2008, 21h00
  2. Problème avec un INSERT
    Par nnj dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 01/08/2006, 15h51
  3. [DREAM MX] Problème avec une insertion d'une anim' flash
    Par Mout85 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 16/09/2005, 12h47
  4. [9i] problème avec trigger after logon
    Par Michael# dans le forum Oracle
    Réponses: 2
    Dernier message: 17/03/2005, 12h14
  5. [MFC] problème avec les insertions dans CComboBox
    Par Joeleclems dans le forum MFC
    Réponses: 12
    Dernier message: 11/06/2004, 15h31

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