Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
Pages : 1
#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....
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
ç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
Pages : 1