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 :

Trigger à l'insertion


Sujet :

PL/SQL Oracle

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2013
    Messages : 8
    Points : 5
    Points
    5
    Par défaut Trigger à l'insertion
    Bonjour,

    Je possède une base de données Oracle 11g Xe avec les 2 tables suivantes :

    tb_mesure (#id_mes, fin_theo_mes,…)
    tb_decision (#id_deci, mes_id (clé étrangère), date_debut_deci, date_fin_deci,…)

    Une mesure possède 0 ou n décisions, et une décision concerne 1 et 1 seule mesure.

    Je souhaiterais avoir un trigger sur la table tb_decision qui effectue la chose suivante :

    Lorsque l’on ajoute pour la première fois une décision qui concerne la mesure #100 (mes_id = 100, par exemple), le champ date_fin_deci de la table tb_decision prenne automatiquement la valeur fin_theo_mes de la table tb_mesure.

    J’ai donc tenté de créer le trigger suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE or REPLACE TRIGGER tr_decisions_dates 
    BEFORE INSERT ON TB_DECISION
    FOR EACH ROW
    DECLARE v_fin_mes DATE;
    BEGIN
      SELECT fin_theo_mes INTO v_fin_mes FROM tb_mesure, tb_decision WHERE :new.mes_id = id_mes; 
      :new.date_fin_deci := v_fin_mes;
    END;
    Mais mon trigger ne fonctionne pas.

    Quelqu'un pourrait-il me conseiller et me dire si je suis dans la bonne direction pour réaliser ce que je souhaite ?

    Merci d'avance pour vos réponses.

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Citation Envoyé par Joël2800 Voir le message
    Mais mon trigger ne fonctionne pas.
    C'est un peu court comme information !
    Le résultat n'est pas celui attendu ?
    Rien ne se passe ?
    Il y a un message d'erreur à l'exécution ? à la compilation ?

    As-tu simplement essayé la requête qui se trouve dans le trigger pour vérifier qu'elle fait bien ce que tu attends ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre averti Avatar de dariyoosh
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 236
    Points : 334
    Points
    334
    Par défaut
    Citation Envoyé par al1_24 Voir le message
    As-tu simplement essayé la requête qui se trouve dans le trigger pour vérifier qu'elle fait bien ce que tu attends ?
    Et à mon avis une question encore plus intéressante: est-ce qu'il a pensé au fonctionnement de ce trigger dans un environnement multi-utilisateur? A l'intérieur de trigger Il fait un simple SELECT alors que rien n'empêche qu'un autre utilisateur dans autre session modifie juste après la valeur de la colonne fin_theo_mes mais qui fait COMMIT avant que la transaction qui a déclenché le trigger soit validée. Il n'est donc pas difficile de se retrouver dans des scénarios où la valeur de la colonne fin_theo_mes dans la table tb_mesure soit complètement différente que celle de la table tb_decision pour une mesure donnée.

    Théoriquement, parfois c'est possible d'imposer les contraintes d'intégrité par des triggers si et seulement si on prévoit un mécanisme de verrouillage correct et cohérent dans les environnements multi-utilisateurs (ce qui n'est pas toujours évident à réaliser), mais assez souvent, avoir recours aux triggers pour assurer des contraintes d'intégrité est due à un mauvais design et une manque de normalisation de la base.
    Cordialement,
    Dariyoosh

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2013
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Merci pour votre réponse.

    Le trigger se compile correctement mais lors de son exécution (insertion dans la table tb_decision) voici le message d'erreur :

    Erreur lors de l'enregistrement des modifications de la table "PULSPLUS"."TB_DECISION" :
    Ligne 3 : ORA-01422: exact fetch returns more than requested number of rows
    ORA-06512: at "PULSPLUS.TR_DECISIONS_DATES", line 5
    ORA-04088: error during execution of trigger 'PULSPLUS.TR_DECISIONS_DATES'
    ORA-06512: at line 1
    Et effectivement, rien ne se passe, l'insertion ne fonctionne pas.
    La structure et la logique de mon trigger sont-elles correct ?

    Merci beaucoup pour votre aide.

  5. #5
    Membre averti Avatar de dariyoosh
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 236
    Points : 334
    Points
    334
    Par défaut
    Apparemment le SELECT renvoie plusieurs lignes alors que la clause INTO devera mettre le résultat dans une seule variable. Il faut donc revoir le SELECT pour savoir pourquoi il y a plusieurs lignes ou comment faire pour réduire le nombre des lignes.

    Et comme j'ai déjà dit, ce trigger ne fonctionnera pas dans un environnement multi-utilisateur.
    Cordialement,
    Dariyoosh

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2013
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    Effectivement, c'est le SELECT qui posait problème. Je l'ai modifié de la manière suivante et ça fonctionne !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE OR REPLACE TRIGGER tr_decisions_dates 
    BEFORE INSERT ON TB_DECISION
    FOR EACH ROW
    DECLARE v_fin_mes DATE;
    BEGIN
      SELECT fin_theo_mes INTO v_fin_mes FROM tb_mesure WHERE :new.mes_id = id_mes; 
      :new.date_fin_deci := v_fin_mes;
    END;
    Maintenant, je voudrais qu'a l'ajout d'une seconde ligne dans la table tb_decision, la colonne date_fin_deci de la dernière ligne insérée prenne comme valeur date_debut_deci de la seconde ligne.

    Il faut donc que je trouve une méthode qui me permette de repérer la dernière ligne insérée, afin que je puise la modifier. Existe-t-il une manière de faire cela dans Oracle ?

    Je vous remercie d’avance pour votre aide.

  7. #7
    Membre averti Avatar de dariyoosh
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 236
    Points : 334
    Points
    334
    Par défaut
    Peut-être j'ai mal compris votre problème, mais je l'ai déjà indiqué dans mon premier commentaire, pour moi votre trigger ne fonctionnera pas dans un environnement multi-utilisateur. Dans votre SELECT , vous pouvez utilisez par exemple la fonction de max (version d'aggregation) afin de récupérer la dernière date, mais rien n'empêche qu'un autre utilisateur dans une session parallèle modifie l'autre table et faire un COMMIT avant même que la transaction déclenchant le trigger ne soit validée, de quoi avoir des valeurs incohérente avec la règle de gestion et des contraintes d'intégrité que vous essayez d'imposer.

    C'est peut-être mon point de vue, mais à mon avis il faut revoir la modélisation de données.
    Cordialement,
    Dariyoosh

Discussions similaires

  1. Insert avec select sur table avec Trigger d'insertion
    Par bran_noz dans le forum Développement
    Réponses: 5
    Dernier message: 23/12/2005, 14h38
  2. pb trigger lors insertion enregistrment!
    Par tooneygirl dans le forum Oracle
    Réponses: 9
    Dernier message: 06/12/2005, 22h57
  3. Créer un trigger "before insert" avec SQL Server
    Par bubi dans le forum Développement
    Réponses: 2
    Dernier message: 14/11/2005, 10h12
  4. [trigger] update inserted?
    Par cosminutza dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 01/06/2005, 09h37
  5. Trigger et insert
    Par jf-nigou dans le forum Oracle
    Réponses: 5
    Dernier message: 16/02/2005, 16h45

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