Précédent   Forum des professionnels en informatique > Bases de données > PostgreSQL > Requêtes
Requêtes Forum d'entraide sur les requêtes SQL spécifiques à PostgreSQL, les triggers, les vues, etc.
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 18/05/2011, 15h29   #1
Invité régulier
 
Inscription : février 2010
Messages : 39
Détails du profil
Informations forums :
Inscription : février 2010
Messages : 39
Points : 7
Points : 7
Par défaut Trigger mise à jour état stock

Bonjour à tous,

j'ai deux tables table articles et table mouvements_article,je voudrais mettre à jour la quantité dans la table articles par un trigger sur la table mouvements_articles est je n'arrive pas ?

Voila le code de la table articles :
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
 
CREATE TABLE articles
(
  id_article bigserial NOT NULL,
  id_sous_famille bigint NOT NULL,
  article character varying(300) NOT NULL,
  designation character varying(300) NOT NULL,
  code character varying(300) NOT NULL,
  id_fournisseur bigint NOT NULL,
  quantite_stock integer,
  quantite_stock_min integer NOT NULL,
  etat_article character varying(60) NOT NULL,
  type_derniere_mouvement character varying(40),
  utilisateur character varying(50),
  datecreation timestamp WITH time zone,
  datemaj timestamp WITH time zone,
  CONSTRAINT pk_article PRIMARY KEY (id_article),
  CONSTRAINT articles_fournisseurs_fk1 FOREIGN KEY (id_fournisseur)
      REFERENCES fournisseurs (id_fournisseur) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE RESTRICT,
  CONSTRAINT articles_sousfamilles_fk1 FOREIGN KEY (id_sous_famille)
      REFERENCES sousfamilles (id_sous_famille) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE RESTRICT,
  CONSTRAINT un_article_code UNIQUE (code),
  CONSTRAINT un_article_nom UNIQUE (article)
)
WITH (
  OIDS=FALSE
);
table mouvements_articles :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
CREATE TABLE mouvements_articles
(
  id_mouvement bigserial NOT NULL,
  id_article bigint NOT NULL,
  type_mouvement character varying(40) NOT NULL,
  numero_bon character varying(40),
  observation character varying(60),
  quantite integer NOT NULL,
  utilisateur character varying(50),
  datecreation timestamp WITH time zone,
  datemaj timestamp WITH time zone,
  CONSTRAINT pk_mouvements_articles PRIMARY KEY (id_mouvement),
  CONSTRAINT mouvements_articles_articles_fk1 FOREIGN KEY (id_article)
      REFERENCES articles (id_article) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE RESTRICT
)
WITH (
  OIDS=FALSE
);
la fonction qui calcule la quantité disponible en stock par différence entre transaction ENTREE et transaction SORTIE
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
 
CREATE OR REPLACE FUNCTION maj_quantite_stock()
  RETURNS TRIGGER AS
$BODY$
 
 DECLARE
 
	int_quantite_stock integer := 0;
        int_id_article_temp integer := 0;
 
    BEGIN
 
IF (TG_OP = 'INSERT') THEN
 
int_id_article_temp = (SELECT id_article FROM mouvements_articles WHERE id_mouvement = NEW.id_mouvement);
int_quantite_stock = (SELECT calcul_quantite_stock (int_id_article_temp));
UPDATE articles SET quantite_stock = int_quantite_stock WHERE articles.id_article = int_id_article_temp;
 
ELSE
int_id_article_temp = (SELECT id_article FROM mouvements_articles WHERE id_mouvement = OLD.id_mouvement);	
int_quantite_stock = (SELECT calcul_quantite_stock(OLD.id_article));
UPDATE articles SET quantite_stock = int_quantite_stock WHERE articles.id_article = int_id_article_temp;
END IF;
 
 
 
        RETURN NEW;
 
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
enfin le code du trigger :

Code :
1
2
3
4
5
6
 
CREATE TRIGGER maj_quantite_stock
  BEFORE INSERT OR UPDATE OR DELETE
  ON mouvements_articles
  FOR EACH ROW
  EXECUTE PROCEDURE maj_quantite_stock();
en résume je voudrais mettre a jour le champ quantite_stock du table articles
pour chaque transaction sur la table mouvements_articles lors d'une requete d'UPDATE / INSERT et aussi DELETE.

Merci d'avance pour l'aide sur le sujet
nouri_t est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2011, 20h36   #2
Modérateur
 
Inscription : octobre 2008
Messages : 1 505
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 505
Points : 2 034
Points : 2 034
quelques remarques:
Le fait que le trigger se déclenche avant l'action (BEFORE INSERT,UPDATE...) parait suspect. Pour ce genre de traitement, ça devrait plutôt être AFTER à mon avis.

La syntaxe
Code :
variable=(SELECT .. FROM ...)
n'est pas valide pour transférer le résultat d'une requête dans une variable. Voir la doc du langage plpgsql pour la bonne syntaxe, avec la clause INTO.
estofilo est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/05/2011, 11h24   #3
Invité régulier
 
Inscription : février 2010
Messages : 39
Détails du profil
Informations forums :
Inscription : février 2010
Messages : 39
Points : 7
Points : 7
Bonjour,

Merci pour votre repense.
après modification du trigger avec AFTER ça marche nickel pour les transactions
INSERT, UPDATE mais ça marche pas pour les transactions DELETE.

Pourrez-vous m'aider SVP ?

nouri_t est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/05/2011, 12h51   #4
Modérateur
 
Inscription : octobre 2008
Messages : 1 505
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 505
Points : 2 034
Points : 2 034
Il faudrait reposter le code de la fonction et peut-être décrire un peu ce que tu entends par "ça ne marche pas".
estofilo est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/05/2011, 13h55   #5
Invité régulier
 
Inscription : février 2010
Messages : 39
Détails du profil
Informations forums :
Inscription : février 2010
Messages : 39
Points : 7
Points : 7
Voila le code de la fonction trigger :

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
 
CREATE OR REPLACE FUNCTION maj_quantite_stock()
  RETURNS TRIGGER AS
$BODY$
 
 DECLARE
 
	int_quantite_stock integer := 0;
        int_id_article_temp integer := 0;
 
    BEGIN
 
IF (TG_OP = 'INSERT') THEN
 
int_id_article_temp = (SELECT id_article FROM mouvements_articles WHERE id_mouvement = NEW.id_mouvement);
int_quantite_stock = (SELECT calcul_quantite_stock (int_id_article_temp));
UPDATE articles SET quantite_stock = int_quantite_stock WHERE articles.id_article = int_id_article_temp;
 
ELSE 
 
IF (TG_OP = 'UPDATE') THEN
int_id_article_temp = (SELECT id_article FROM mouvements_articles WHERE id_mouvement = OLD.id_mouvement);	
int_quantite_stock = (SELECT calcul_quantite_stock(int_id_article_temp));
UPDATE articles SET quantite_stock = int_quantite_stock WHERE articles.id_article = int_id_article_temp;
 
 
ELSE 
 
IF (TG_OP = 'DELETE') THEN
 
int_id_article_temp = (SELECT id_article FROM mouvements_articles WHERE id_mouvement = OLD.id_mouvement);	
int_quantite_stock = (SELECT calcul_quantite_stock(int_id_article_temp));
UPDATE articles SET quantite_stock = int_quantite_stock WHERE articles.id_article = int_id_article_temp;
END IF;
 
END IF;
END IF;
 
 
 
 
        RETURN NEW;
 
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
et le code de la fonction calcul_quantite_stock c'est :

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
 
CREATE OR REPLACE FUNCTION calcul_quantite_stock(idarticle bigint)
  RETURNS character AS
$BODY$
DECLARE
 
	intSomme_mvt_entree integer := 0;
	intSomme_mvt_sortie integer := 0;
	intQuantite_stock_article integer := 0;
 
 
BEGIN
 
intSomme_mvt_entree = (SELECT SUM (quantite) FROM mouvements_articles WHERE mouvements_articles.id_article = idarticle AND mouvements_articles.type_mouvement = 'ENTREE');
 
IF intSomme_mvt_entree IS NULL THEN
intSomme_mvt_entree := 0;
END IF;
 
intSomme_mvt_sortie = (SELECT SUM (quantite) FROM mouvements_articles WHERE mouvements_articles.id_article = idarticle AND mouvements_articles.type_mouvement = 'SORTIE');
 
IF intSomme_mvt_sortie IS NULL THEN
intSomme_mvt_sortie := 0;
END IF;
 
intQuantite_stock_article = intSomme_mvt_entree - intSomme_mvt_sortie;
 
	RETURN intQuantite_stock_article;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
pour "ça ne marche pas" :

le pb c'est que le champ quantite_stock de la table articles ne se met pas à jour apres une transaction DELETE sur la tables mouvements_articles.

je voudrais si je supprime une ligne de la table mouvements_articles le trigger de cette table doit mettre à jour le champ quantite_stock de la table articles.

OK pour transaction SELECT,UPDATE, mais pas pour le DELETE, en faite après suppression de toutes les lignes pour un articles dans la table mouvements_articles, je regarde coté table articles je trouve que la quantite_stock reste la même pourtant dans la table mouvements_articles pas de ligne pour l'article en question.

MERCI Bien
nouri_t est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/05/2011, 14h24   #6
Modérateur
 
Inscription : octobre 2008
Messages : 1 505
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 505
Points : 2 034
Points : 2 034
Dans le cas du DELETE, la requête
Code :
SELECT id_article FROM mouvements_articles WHERE id_mouvement = OLD.id_mouvement
ne va rien renvoyer puisque justement la ligne a été effacée.
L'information cherchée est dans OLD.id_article, il ne faut pas faire de requête pour la trouver.

Accessoirement il en est de même pour UPDATE ou INSERT, il suffit de prendre NEW.id_article, la requête est inutile.
estofilo est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Vieux 19/05/2011, 14h57   #7
Invité régulier
 
Inscription : février 2010
Messages : 39
Détails du profil
Informations forums :
Inscription : février 2010
Messages : 39
Points : 7
Points : 7
Merci !

ça marche.
nouri_t 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 14h42.


 
 
 
 
Partenaires

Hébergement Web