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

SQL Oracle Discussion :

Problème de trigger : table is mutating


Sujet :

SQL Oracle

  1. #1
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut Problème de trigger : table is mutating
    Bonjour,
    Cette fois, je veux assigner une valeur à une colonne d'une table sur modification d'une autre colonne de cette même table. Mais la valeur à assigner vient d'une autre table. Dans ma première version qui a déclenché le message, j'avais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create or replace trigger graphical_point_runway 
    before update of heading#runway on graphical_point
    begin
     update graphical_point set length=(select length from runway
     where airspace_env_name=:new.airspace_env_name#runway and heading=:new.heading#runway and runway_distinction=:new.runway_distinction#runway)
     where :old.heading#runway=:new.heading#runway and :old.runway_distinction#runway=:new.runway_distinction#runway;
    end;
    /
    Je peux comprendre l'erreur car je cherche à faire un update sur un record déjà en update. C'est peut être un pb de syntaxe mais je ne sais pas comment aller chercher la valeur de la table RUNWAY sans mettre dans le trigger le UPDATE GRAPHICAL_POINT ... (SELECT ... FROM RUNWAY) WHERE ...
    Passer par une table temporaire me semble compliqué pour ce que je veux faire, non ?
    Merci

    Mes tables :
    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
    SQL> desc graphical_point
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     AIRSPACE_ENV_NAME                         NOT NULL VARCHAR2(20)
     NAME                                      NOT NULL VARCHAR2(16)
     KIND                                      NOT NULL VARCHAR2(15)
     AIRSPACE_ENV_NAME#GEO_PT                           VARCHAR2(20)
     POINT_NAME#GEO_PT                                  VARCHAR2(5)
     AIRSPACE_ENV_NAME#AIRPORT                          VARCHAR2(20)
     AIRPORT_CODE#AIRPORT                               VARCHAR2(4)
     AIRSPACE_ENV_NAME#RUNWAY                           VARCHAR2(20)
     AIRPORT_CODE#RUNWAY                                VARCHAR2(4)
     HEADING#RUNWAY                                     NUMBER(38)
     RUNWAY_DISTINCTION#RUNWAY                          VARCHAR2(1)
     AIRSPACE_ENV_NAME#HOLD                             VARCHAR2(20)
     HOLD_NAME#HOLD                                     VARCHAR2(20)
     LATITUDE                                           VARCHAR2(7)
     LONGITUDE                                          VARCHAR2(8)
     LENGTH                                             NUMBER(38)
     RUNWAY_HEADING                                     NUMBER(38)
     ORIENTATION                                        NUMBER(4,1)
     TURN_DIRECTION                                     VARCHAR2(1)
     LEG_LENGTH                                         NUMBER(38)
     LEG_TIME                                           NUMBER(38)
     MAPS_USAGE_DESCRIPTOR                              VARCHAR2(64)
     
    SQL> desc runway
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     AIRSPACE_ENV_NAME                         NOT NULL VARCHAR2(20)
     AIRPORT_CODE                              NOT NULL VARCHAR2(4)
     RUNWAY_DISTINCTION                                 VARCHAR2(1)
     HEADING                                   NOT NULL NUMBER(38)
     AIRSPACE_ENV_NAME#GEO_PT                  NOT NULL VARCHAR2(20)
     POINT_NAME#GEO_PT                         NOT NULL VARCHAR2(5)
     WIDTH                                              NUMBER(3,2)
     LENGTH                                             NUMBER(38)
     
    SQL>

  2. #2
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Ne faite pas d'update, mais calculer juste la nouvelle valeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    :new.variable := foo(:new.param);

  3. #3
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut
    Que voulez vous dire ? foo doit être une procédure qui fera le select dont j'ai besoin ?
    Merci

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE OR REPLACE TRIGGER graphical_point_runway 
    before UPDATE of heading#runway on graphical_point
    begin
       SELECT length
         INTO :new.length
         FROM runway
        WHERE airspace_env_name  = :new.airspace_env_name#runway
          and heading            = :new.heading#runway
          and runway_distinction = :new.runway_distinction#runway;
    end;
    /

  5. #5
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par awalter1 Voir le message
    Que voulez vous dire ? foo doit être une procédure qui fera le select dont j'ai besoin ?
    Merci
    Pas forcement quoi que c'est une bonne pratique.

  6. #6
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut
    Le trigger n'est pas accepté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SQL> create or replace trigger graphical_point_runway
    before update of heading#runway on graphical_point
    begin
    select length into :new.length from runway
    where airspace_env_name=:new.airspace_env_name#runway and heading=:new.heading#runway and runway_distinction=:new.runway_distinction#runway;
    end;
     /
    create or replace trigger graphical_point_runway
                              *
    ERROR at line 1:
    ORA-04082: NEW or OLD references not allowed in table level triggers
     
    SQL>
    J'ai ajouté la ligne "for each row" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SQL> create or replace trigger graphical_point_runway
      2  before update of heading#runway on graphical_point
     for each row
      3    4  begin
      5   select length into :new.length from runway
      6   where airspace_env_name=:new.airspace_env_name#runway and heading=:new.heading#runway and runway_distinction=:new.runway_distinction#runway;
      7  end;
      8  /
     
    Trigger created.
     
    SQL>
    J'ai alors une erreur lors de l'update du record :
    ********************* ERROR ************************
    Class = Record
    Method = Record_SelfUpdate
    Message = ['', 'ORA-01403: no data found\nORA-06512: at "TST13A.GRAPHICAL_POINT_RUNWAY", line 2\nORA-04088: error during execution of trigger \'TST13A.GRAPHICAL_POINT_RUNWAY\'\n']
    ****************************************************
    Je pense que les valeurs prises par :new ne sont pas correctes au moment de l'exécution du trigger, du coup il ne trouve pas de record. J'ai essayé avec le trigger suivant (je vais chercher un record qui existe dans la table runway) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create or replace trigger graphical_point_runway 
    before update of heading#runway on graphical_point
     for each row 
    begin
     select length into :new.length from runway
     where airspace_env_name='MAASNEW' and heading='26';
    end;
    /
    Dans ce cas l'attribut length est correctement renseigné !
    Merci

  7. #7
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut
    Finalement, je n'utilise pas de trigger, je gère l'update des champs dans mon code.
    Merci de votre participation

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

Discussions similaires

  1. Trigger: table en mutation
    Par JCD21 dans le forum Débuter
    Réponses: 10
    Dernier message: 16/08/2011, 14h19
  2. [Oracle8i][Trigger]Table en mutation
    Par Drizzt [Drone38] dans le forum Administration
    Réponses: 6
    Dernier message: 06/11/2009, 13h58
  3. Problème avec trigger (table INSERTED)
    Par ygrim dans le forum Développement
    Réponses: 1
    Dernier message: 20/04/2008, 21h00
  4. Problème de Trigger inter-table
    Par baptx dans le forum PL/SQL
    Réponses: 7
    Dernier message: 24/05/2007, 17h19
  5. [Oracle 8i] Problème Trigger-Table
    Par lper dans le forum SQL
    Réponses: 4
    Dernier message: 03/04/2007, 17h16

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