Vous n'êtes pas identifié(e).

#1 16/05/2011 10:20:34

NOURI
Membre

Trigger gestion stock

Bonjour à tous,

j'ai un problème avec un trigger qui me permet de mettre à jour l’état d'un stock ('EN STOCK' / 'A COMMANDER')

la table est la suivante :

CREATE TABLE articles
(
  id_article bigserial NOT NULL,
  id_sous_famille bigint NOT NULL,
  code character varying(300) NOT NULL,
  article character varying(300) NOT NULL,
  designation character varying(300) NOT NULL,
  id_fournisseur bigint NOT NULL,
  quantite_stock integer NOT NULL,
  quantite_stock_min integer NOT NULL,
  etat_article character varying(60) NOT NULL,
  type_derniere_mouvement character varying(40) NOT NULL,
  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_designation UNIQUE (designation)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE articles OWNER TO postgres;

et le code du trigger est :

CREATE OR REPLACE FUNCTION maj_etat_stock()
  RETURNS trigger AS
$BODY$
DECLARE
	
int_quantite_stock integer;
int_quantite_stock_min integer;
intId_id_article bigint;

BEGIN
-- pour chaque mouvement on cherche la quantité, et la quantité min ...
SELECT articles.id_article,
articles.quantite_stock,
articles.quantite_stock_min 

INTO intId_id_article,
int_quantite_stock,
int_quantite_stock_min

FROM articles

WHERE articles.id_article = NEW.id_article; -- pour chaque INSERT / UPDATE

-------------------------------------------------------------------------------------------

IF (int_quantite_stock > int_quantite_stock_min) THEN

UPDATE articles SET etat_article = 'EN STOCK' WHERE articles.id_article = NEW.id_article;

ELSE

UPDATE articles SET etat_article = 'A COMMANDER' WHERE articles.id_article = NEW.id_article;

END IF;

RETURN NULL;

END;

$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION maj_etat_stock() OWNER TO postgres;

je fais UPDATE, INSERT dans la table articles, mais toujours l'etat du stock reste la même !

Pourrez-vous m'aider à trouver une solution ?

MERCI d'avance.


Cordiales Salutations

Hors ligne

#2 16/05/2011 10:39:02

Marc Cousin
Membre

Re : Trigger gestion stock

Avant de chercher une solution complexe au problème, il y a eu une commande 'CREATE  TRIGGER' de passée ?


Marc.

Hors ligne

#3 16/05/2011 12:16:46

NOURI
Membre

Re : Trigger gestion stock

MERCI Marc !

après passage de la commande :

CREATE TRIGGER maj_etat_stock
  after INSERT or update
  ON articles
  FOR EACH ROW
  EXECUTE PROCEDURE maj_etat_stock();

je lance la commande :

UPDATE articles SET quantite_stock = '200' WHERE id_article = '35';

pg_admin me répandre :
ERREUR:  dépassement de limite (en profondeur) de la pile
HINT:  Augmenter le paramètre « max_stack_depth » après vous être assuré que la
limite de profondeur de la pile de la plateforme est adéquate.
CONTEXT:  instruction SQL « SELECT 1 FROM ONLY "public"."fournisseurs" x WHERE "id_fournisseur" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x »
instruction SQL « UPDATE articles SET etat_article = 'EN STOCK' WHERE articles.id_article = NEW.id_article »
PL/pgSQL function "maj_etat_stock" line 25 at instruction SQL
instruction SQL « UPDATE articles SET etat_article = 'EN STOCK' WHERE articles.id_article = NEW.id_article »
PL/pgSQL function "maj_etat_stock" line 25 at instruction SQL
instruction SQL « UPDATE articles SET etat_article = 'EN STOCK' WHERE articles.id_article = NEW.id_article »
PL/pgSQL function "maj_etat_stock" line 25 at instruction SQL
instruction SQL « UPDATE articles SET etat_article = 'EN STOCK' WHERE articles.id_article = NEW.id_article »
PL/pgSQL function "maj_etat_stock" line 25 at instruction SQL
instruction SQL « UPDATE articles SET etat_article = 'EN STOCK' WHERE articles.id_article = NEW.id_article »
PL/pgSQL function "maj_etat_stock" line 25 at instruction SQL
instruction SQL « UPDATE articles SET etat_article = 'EN STOCK' WHERE articles.id_article = NEW.id_article »
PL/pgSQL function "maj_etat_stock" line 25 at instruction SQL
instruction SQL « UPDATE articles SET etat_article = 'EN STOCK' WHERE articles.id_article = NEW.id_article »
PL/pgSQL function "maj_etat_stock" line 25 at instruction SQL
instruction SQL « UPDATE articles SET etat_article = 'EN STOCK' WHERE articles.id_article = NEW.id_article »
PL/pgSQL function "maj_etat_stock" line 25 at instruction SQL

...


Cordiales Salutations

Hors ligne

#4 16/05/2011 12:57:45

Marc Cousin
Membre

Re : Trigger gestion stock

En fait, c'est l'enregistrement modifié au moment du déclenchement du trigger que vous voulez modifier dans le trigger, si j'ai bien compris ? Parce que là, effectivement, vous mettez à jour l'enregistrement si il est mis à jour, ce qui redéclenche le trigger en boucle, d'où le message de récursion.


Marc.

Hors ligne

#5 16/05/2011 13:37:24

NOURI
Membre

Re : Trigger gestion stock

Merci Marc pour l'aide.

je voudrais mettre à jour l'état du stock (c'est à dire la valeur de la colonne etat_article)

pour un UPDATE OR INSERT je dois vérifier si quantite_stock > quantite_stock_min si c'est le cas je mettre à jour la colonne  :
etat_article = 'EN STOCK'


sinon (quantite_stock < quantite_stock_min), je mettre etat_article = 'A COMMANDER'

merci


Cordiales Salutations

Hors ligne

#6 16/05/2011 13:47:10

Marc Cousin
Membre

Re : Trigger gestion stock

En fait, il suffit de déclarer le trigger comme étant for each row, et before. Et ensuite, de manipuler directement la variable NEW.
Cf :
http://docs.postgresql.fr/9.0/plpgsql-trigger.html (     Rappelons-nous qui a changé le salaire et quand )


Marc.

Hors ligne

#7 16/05/2011 14:58:35

SQLpro
Membre

Re : Trigger gestion stock

Quel est donc l'intérêt de faire un trigger complexe couteux et que visiblement vous ne maitrisez pas....

NOURI a écrit :

je voudrais mettre à jour l'état du stock (c'est à dire la valeur de la colonne etat_article)

pour un UPDATE OR INSERT je dois vérifier si quantite_stock > quantite_stock_min si c'est le cas je mettre à jour la colonne  :
etat_article = 'EN STOCK'

sinon (quantite_stock < quantite_stock_min), je mettre etat_article = 'A COMMANDER'

...alors que la solution est d'utiliser une vue ?

RAPPEL : toutes les applications que l'on développe avec accès à une base de données relationnelle, devraient faire appel exclusivement à des vues (et éventuellement des procédures stockées). Cela s’appelle le MED ou Modèle Externe de Données.

Dans votre cas :

1) La bonne table

CREATE TABLE articles
(
  id_article              bigserial NOT NULL,
  id_sous_famille         bigint NOT NULL,
  code                    character varying(300) NOT NULL,
  article                 character varying(300) NOT NULL,
  designation             character varying(300) NOT NULL,
  id_fournisseur          bigint NOT NULL,
  quantite_stock          integer NOT NULL,
  quantite_stock_min      integer NOT NULL,
  type_derniere_mouvement character varying(40) NOT NULL,
  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_designation UNIQUE (designation)
)

2) La vue

CREATE VIEW V_articles
AS
SELECT *,
       CASE 
          WHEN quantite_stock >= quantite_stock_min THEN 'EN STOCK'
          WHEN quantite_stock < quantite_stock_min 'A COMMANDER'
          ELSE NULL
       END AS etat_article
FROM   articles

N'oubliez par qu'une vue peut être mise à jour, sauf pour les colonnes dérivées (constantes, calcules...)

A +

Dernière modification par SQLpro (16/05/2011 14:59:43)


Frédéric Brouard, alias SQLpro,  ARCHITECTE DE DONNÉES,  Expert langage SQL
Le site sur les SGBD relationnel et langage SQL   : http://sqlpro.developpez.com/
Modélisation de données, conseil, expertise, audit, optimisation, tuning, formation
* * * * *  Enseignant CNAM PACA, ISEN Toulon,  CESI Aix en Provence  * * * * *

Hors ligne

#8 16/05/2011 15:37:14

NOURI
Membre

Re : Trigger gestion stock

MERCI wink

ça marche

Voila mon code

CREATE FUNCTION maj_etat_stock() RETURNS trigger AS $maj_etat_stock$
    BEGIN
    
         -- Verifie que etat_article est donnés
        IF NEW.etat_article IS NULL THEN
            RAISE EXCEPTION 'etat_article ne peut pas être NULL';
        END IF;
        
        -- Verifie si la quantité en à ajouter / mettre à jour est > a la qte min en stock
        IF NEW.quantite_stock > NEW.quantite_stock_min THEN

        -- Mettre l'état 'EN STOCK'
         NEW.etat_article  := 'EN STOCK';
         
         ELSE
          -- Mettre l'état 'A COMMANDER'
          NEW.etat_article  := 'A COMMANDER';
 
        END IF;
        
        RETURN NEW;
        
    END;
$maj_etat_stock$ LANGUAGE plpgsql;

CREATE TRIGGER maj_etat_stock BEFORE INSERT OR UPDATE ON articles
    FOR EACH ROW EXECUTE PROCEDURE maj_etat_stock();

Cordiales Salutations

Hors ligne

#9 16/05/2011 17:37:57

gleu
Administrateur

Re : Trigger gestion stock

SQLpro, les commentaires du style "et que visiblement vous ne maitrisez pas", j'aimerais que cela s'arrête définitivement. On n'a jamais banni qui que ce soit ici, j'aimerais mieux ne pas avoir à y être contraint, mais je n'hésiterai pas à le faire si votre mauvais comportement continue.


Guillaume.

Hors ligne

#10 16/05/2011 17:41:27

gleu
Administrateur

Re : Trigger gestion stock

Et du coup, j'oubliais aussi de dire que la vue, c'est bien beau, mais c'est pas modifiable sauf à lui ajouter une règle qui est plus complexe à mettre en place qu'un trigger.


Guillaume.

Hors ligne

#11 17/05/2011 10:17:59

NOURI
Membre

Re : Trigger gestion stock

Bonjour à tous,

Euh … encore une fois SQLpro avec ces commentaires de …, à l’instant ou j’ai répandu à Marc j’ai pas vue leur message de merde, je parle de ça c’est juste pour dire que le MERCI c’est pour Marc, c’est pas pour toi Mr Pro !


J’ai regardé coté developpez.com et autre sites, toujours la même personne parle les même phrases (ne connaissez rien, difficile, bêtise, merde, bizarre, blabla, …)

SQLpro essayer d’être plus professionnelle, arrêter de traiter les choses de cette façon, les personnes viennent ici pour prendre c’est pas pour voir vos messages …

Regarde bien la qualité des réponses de Marc, de Guillaume, … c’est vraiment un vrai support pour partager, pour prendre, pour connaître, pour respecter les autres …

A Propos, c’est hors sujet, mais pour info, je ne suis pas ni DBA, ni un spécialiste SQL, je code essentiellement en  C / WinDev, je suis un spécialiste bancs de tests & mesures …

Encore une fois MERCI d’être plus ouvert, plus professionnelle …

Guillaume, Marc, exécutez-moi de cette façon, mais vraiment …

Allez Bonne journée, conteniez à développez ce super forum.


Cordiales Salutations

Hors ligne

Pied de page des forums