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 :

Problème trigger sur plusieurs tables


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vosges (Lorraine)

    Informations forums :
    Inscription : Août 2011
    Messages : 103
    Par défaut Problème trigger sur plusieurs tables
    Bonjour, voila j'ai un problème avec un trigger que j'essaie de faire depuis deux jours. En fait j'ai 3 tables : serveurs, commande et affecter. J'ai un champ compteur dans la table serveur qui doit s'incrémenter/décrémenter quand celui-ci est affecté à une commande mais je bloque un peu.

    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
     
    create or replace trigger compte_commande after
    insert or delete on serveurs
    for each row
    begin
    if deleting then
    SELECT compteur
    INTO :old.compteur - 1
    FROM serveurs;
    elsif inserting then
    SELECT compteur
    INTO :old.compteur + 1
    FROM serveurs;
    end if;
    end;
    le déclencheur se crée mais avec des erreurs de compilations :

    L 3 et L 7 : Statement ignored
    L4 et L 8 : mot clé FROM absent à l'emplacement prévu

    Merci de votre aide

  2. #2
    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
    Le déclencheur doit être mis sur la table affecter, pas sur la table serveurs.

    Objets
    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
    49
    50
    create table serveurs
    (
        id_serveur integer not null
      , compteur   integer not null
      , constraint pk_serveurs
          primary key (id_serveur)
          using index
    );
     
    create table commande
    (
        id_commande integer not null
      , constraint pk_commande
          primary key (id_commande)
          using index
    );
     
    create table affecter
    (
        id_commande integer not null
      , id_serveur  integer not null
      , constraint pk_affecter
          primary key (id_commande, id_serveur)
      , constraint fk_affecter_commande
          foreign key (id_commande) 
          references commande
      , constraint fk_affecter_serveur
          foreign key (id_serveur) 
          references serveurs
    );
     
    CREATE OR REPLACE TRIGGER taid_cnt_commande
    AFTER INSERT OR DELETE ON affecter
    FOR EACH ROW
    declare
        v$_sens        integer;
        v$_id_serveur  serveurs.id_serveur%type;
    begin
        IF deleting then
          v$_sens := -1;
          v$_id_serveur := :old.id_serveur;
        ELSIF inserting then
          v$_sens := +1;
          v$_id_serveur := :new.id_serveur;
        END IF;
        UPDATE serveurs srv
           SET srv.compteur = srv.compteur + v$_sens
         WHERE srv.id_serveur = v$_id_serveur;
    end;
    /
    Données
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    insert into serveurs (id_serveur, compteur) values (1, 0);
    -- 1 row created.
    insert into serveurs (id_serveur, compteur) values (2, 0);
    -- 1 row created.
     
    insert into commande (id_commande) values (1);
    -- 1 row created.
    insert into commande (id_commande) values (2);
    -- 1 row created.
    insert into commande (id_commande) values (3);
    -- 1 row created.
     
    commit;
    -- Commit complete.
     
    insert into affecter (id_commande, id_serveur) values (1, 1);
    -- 1 row created.
     
    select * from serveurs;
     
    ID_SERVEUR   COMPTEUR
    ---------- ----------
             1          1
             2          0
     
    insert into affecter (id_commande, id_serveur) values (2, 1);
    -- 1 row created.
     
    select * from serveurs;
     
    ID_SERVEUR   COMPTEUR
    ---------- ----------
             1          2
             2          0
     
    insert into affecter (id_commande, id_serveur) values (3, 1);
    -- 1 row created.
     
    select * from serveurs;
     
    ID_SERVEUR   COMPTEUR
    ---------- ----------
             1          3
             2          0
     
    insert into affecter (id_commande, id_serveur) values (3, 2);
    -- 1 row created.
     
    select * from serveurs;
     
    ID_SERVEUR   COMPTEUR
    ---------- ----------
             1          3
             2          1
     
    delete from affecter
     where id_serveur = 1;
    -- 3 rows deleted.
     
    select * from serveurs;
     
    ID_SERVEUR   COMPTEUR
    ---------- ----------
             1          0
             2          1
    De mon côté je préfère effectuer le comptage à la volée, dans une vue par exemple.

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vosges (Lorraine)

    Informations forums :
    Inscription : Août 2011
    Messages : 103
    Par défaut probleme triggers plusieurs table
    merci pour ton exemple Waldar qui est très bien expliqué mais en fait j'avais simplifié la chose pour comprendre.
    J'ai 4 tables : serveurs avec idserveur (clé primaire)
    table avec idtable (clé primaire)
    affecter (association) avec idserveur et id table (2 clé primaire)
    et commande avec idcommande (clé primaire) et idtable (clé secondaire)

    donc en fait la question est plus sur le fait de comment fonctionne un trigger avec plusieurs tables ?

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vosges (Lorraine)

    Informations forums :
    Inscription : Août 2011
    Messages : 103
    Par défaut nouvel essai qui ne marche pas
    Voila j'ai essayé autre chose mais le déclencheur se crée mais à l'éxécution il me dit que la table commande est en mutation ???

    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
     
    create or replace trigger compte before
    insert or update or delete on commandes
    for each row
    declare
    sens integer;
    idserv serveurs.idserveur%type;
    begin
    select s.idserveur
    into idserv
    from commandes c,les_tables t,affecter a,serveurs s
    where c.idtable = t.idtable
    and t.idtable = a.idtable
    and a.idserveur = s.idserveur
    and a.idtable = :new.idtable
    and a.dateaffectation = :new.date_enregistrement;
    if inserting then
     sens := +1 ;
    else
     sens := -1;
    end if;
    update serveurs s
    set s.compteur = s.compteur + sens
    where idserveur = idserv;
    end;

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par thomasaurelien Voir le message
    Voila j'ai essayé autre chose mais le déclencheur se crée mais à l'éxécution il me dit que la table commande est en mutation ???
    http://sgbd.developpez.com/oracle/ora-04091/

  6. #6
    Membre confirmé
    Inscrit en
    Mai 2010
    Messages
    193
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 193
    Par défaut
    Moi j'ai trouvé mais bon si je te le dit le prof va nous retirer des points........

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

Discussions similaires

  1. Problème update sur plusieurs tables
    Par Fabdeuche dans le forum SQL
    Réponses: 4
    Dernier message: 22/04/2010, 16h16
  2. Réponses: 5
    Dernier message: 19/06/2009, 16h33
  3. [JTable] problème filtrage sur plusieurs table
    Par MustOne dans le forum Composants
    Réponses: 3
    Dernier message: 10/06/2009, 10h00
  4. Problème requete sur plusieurs tables
    Par sigmoun dans le forum Requêtes
    Réponses: 4
    Dernier message: 19/01/2009, 00h32
  5. problème delete sur plusieurs tables
    Par soubre dans le forum Hibernate
    Réponses: 4
    Dernier message: 19/06/2008, 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