Précédent   Forum des professionnels en informatique > Bases de données > Oracle > PL/SQL
PL/SQL Forum d'entraide sur le PL/SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/01/2012, 19h05   #1
Invité régulier
 
Homme
Inscription : août 2011
Messages : 56
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Vosges (Lorraine)

Informations forums :
Inscription : août 2011
Messages : 56
Points : 9
Points : 9
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 :
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
thomasaurelien est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 19h30   #2
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Le déclencheur doit être mis sur la table affecter, pas sur la table serveurs.

Objets
Code :
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 :
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.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 22h15   #3
Invité régulier
 
Homme
Inscription : août 2011
Messages : 56
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Vosges (Lorraine)

Informations forums :
Inscription : août 2011
Messages : 56
Points : 9
Points : 9
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 ?
thomasaurelien est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2012, 19h11   #4
Invité régulier
 
Homme
Inscription : août 2011
Messages : 56
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Vosges (Lorraine)

Informations forums :
Inscription : août 2011
Messages : 56
Points : 9
Points : 9
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 :
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;
thomasaurelien est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/01/2012, 19h19   #5
Expert Confirmé
 
Avatar de 7gyY9w1ZY6ySRgPeaefZ
 
Homme
dba
Inscription : juillet 2007
Messages : 2 523
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Canada

Informations professionnelles :
Activité : dba

Informations forums :
Inscription : juillet 2007
Messages : 2 523
Points : 3 972
Points : 3 972
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/
__________________
les règles du forum - mode d'emploi du forum
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs.
(Rappel : "ça ne marche pas" n'est pas un message d'erreur)
JE NE RÉPONDS PAS aux questions techniques par message privé.
Écrire en français sur un forum est une marque minimale de respect.
7gyY9w1ZY6ySRgPeaefZ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2012, 19h26   #6
Candidat au titre de Membre du Club
 
Lecompte Remi
Inscription : mai 2010
Messages : 57
Détails du profil
Informations personnelles :
Nom : Lecompte Remi

Informations forums :
Inscription : mai 2010
Messages : 57
Points : 12
Points : 12
Moi j'ai trouvé mais bon si je te le dit le prof va nous retirer des points........
bob456 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 21h45.


 
 
 
 
Partenaires

Hébergement Web