SQL TRIGGER Duplicata clé primaire [Résolu]

Signaler
Messages postés
54
Date d'inscription
samedi 3 avril 2021
Statut
Membre
Dernière intervention
8 mai 2021
-
Messages postés
15564
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 mai 2021
-
Bonjour, merci d'avance pour votre aide.

j'ai une table products avec un pro_id un pro_stock et pro_stock_alert. Une table commander_articles avec un codart qte et date.
Donc à chaque fois que je modifie le pro_stock le trigger l'affiche dans commander_articles et seulement s'il est inférieur au pro_stock_alert.

mes exemples à voir dans "Modification" :
pour le premier cela fonctionne rien n'a afficher

pour le deuxième cela fonctionne la ligne est ajouté

mais le troisième du coup ne fonctionne pas il me donne l'erreur suivante

#1062 - Duplicata du champ '8' pour la clef 'commander_articles.PRIMARY'

j'ai compris qu'il pouvait y avoir qu'un id,
j'ai essayé en retirant l'auto-incrementation echec
j'ai essayé en retirant NEW.pro_id de VALUE et laissé l'auto-incrementation echec

j'ai compris le fond du problème mais je ne vois pas exactement comment faire pour éviter le duplicata de l'id

si j'ai pas étais clair dans mes explications faite le moi savoir



-- Structure de la table `products`


DROP TABLE IF EXISTS `products`;
CREATE TABLE IF NOT EXISTS `products` (
  `pro_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
 `pro_stock` int(5) UNSIGNED NOT NULL,
  `pro_stock_alert` int(5) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



-- Structure de la table `commander_articles`


DROP TABLE IF EXISTS `commander_articles`;
CREATE TABLE IF NOT EXISTS `commander_articles` (
  `codart` INT(10) UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
  `qte` INT NOT NULL,
  `date` DATE NOT NULL,

 FOREIGN KEY(`codart`) REFERENCES `products`(`pro_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


 --TRIGGER  -- 

DELIMITER |
CREATE TRIGGER after_update_products
AFTER UPDATE ON products 
FOR EACH ROW
BEGIN
    DECLARE t_pro_id INT; 
    DECLARE t_stock INT; 
    DECLARE t_stock_alert INT; 
    SET t_pro_id = new.pro_id;
    SET t_stock = (SELECT pro_stock FROM products WHERE pro_id = new.pro_id);  
    SET t_stock_alert = (SELECT pro_stock_alert FROM products WHERE pro_id = new.pro_id);  
    IF(t_stock < t_stock_alert) 
    THEN
    INSERT INTO commander_articles (codart, qte, date) VALUES (NEW.pro_id, t_stock_alert - t_stock, NOW()); 
    END IF;
END |
DELIMITER ;

------ Modification ------

UPDATE products
SET pro_stock = 6

UPDATE products
SET pro_stock = 4
WHERE pro_id = 8

UPDATE products
SET pro_stock = 3
WHERE pro_id = 8


Configuration: Windows / Chrome 90.0.4430.85

3 réponses

Messages postés
15564
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 mai 2021
850
bonjour,
quel est d'après toi le fond du problème?
as-tu conçu ces tables?
Messages postés
54
Date d'inscription
samedi 3 avril 2021
Statut
Membre
Dernière intervention
8 mai 2021

Bonjour, alors la table products existait déjà j’ai en revanche conçu la table commander_article.
Et pour réponse à ta question pour moi le fond du problème c'est la clé primaire qui, elle fait que chaque id doit être unique dans toute la table... d’où le duplicata (plus de 1 id). Donc je pense qu'il faut logiquement que je trouve le moyen de n'avoir qu'1 ligne par n° produit dans cette table ?
Messages postés
15564
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 mai 2021
850 >
Messages postés
54
Date d'inscription
samedi 3 avril 2021
Statut
Membre
Dernière intervention
8 mai 2021

je pense que tu abordes le problème à l'envers.
tu dois définir tes tables en fonction de ta situation, et non le contraire.
peux-tu, oui ou non, avoir plusieurs commandes pour le même article? si oui, ta table "commandes" est mal conçue.
Messages postés
15564
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 mai 2021
850 >
Messages postés
15564
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 mai 2021

par ailleurs, comprends-tu à quoi sert
AUTO_INCREMENT
?
pourquoi l'as-tu écrit en ligne 19?
Messages postés
54
Date d'inscription
samedi 3 avril 2021
Statut
Membre
Dernière intervention
8 mai 2021
>
Messages postés
15564
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 mai 2021

Oui l’auto_increment sert à énumérer automatiquement n+1 à chaque ajout et je l’ai écris par habitude comme c’est une clé primaire je lui met toujours auto_increment chose que un j’ai vérifié en premier lieu et non il ne peut y avoir plusieurs commandes suppliers pour le même produits
Messages postés
15564
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 mai 2021
850 >
Messages postés
54
Date d'inscription
samedi 3 avril 2021
Statut
Membre
Dernière intervention
8 mai 2021

Je pense que, surtout pour un débutant, il faut éviter de travailler par habitude. Cela a-t-il du sens de créer une valeur automatique pour le champ en ligne 19?

Tout cela me semble de moins en moins clair. Que vient faire "suppliers" dans ta dernière phrase? Je pense préférable de ne pas mélanger plusieurs langues dans la même phrase.

Prends peut-être le temps d'expliquer en français à quoi servent chacun des champs de tes tables.
Messages postés
54
Date d'inscription
samedi 3 avril 2021
Statut
Membre
Dernière intervention
8 mai 2021

Comme je vous l'ai dis plus haut, j'ai retiré le auto_increment dès le début comme vous dite pas de sens deplus aucun changement... le suppliers n'en prenez pas compte c'est comme si je vous disais le auto-increment a était écrit par moi, j'ai pas fais attention en l'écrivant,
il ne peut y avoir plusieurs commandes pour le même produits cela reste idem.

Donc j'ai ma table products qui veux dire produit en français.
Il y a dedans un pro_id exemple 8
un pro_stock qui est le stock physique exemple 6
et un pro_stock_alert qui est le stock d'alerte qui est de 5.

Alors mntn à chaque fois que je modifie mon pro_stock 8, 10, 100 il n'y rien ma valeur est supérieur au pro_stock_alert.
Mais si le pro_stock est inférieur au pro_stock_alert, moins de 5 ,une ligne se crée dans ma table commander_article avec le pro_id qui correspond au codart, qte au stock réel restant et date à la date du jour de la modification.
Messages postés
15564
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 mai 2021
850
si tu as retiré le auto_increment dès le début, peux-tu alors montrer le code que tu utilises?
quand tu écris "une ligne se crée dans ma table", c'est ce que tu souhaites, ou c'est ce qui se passe?

je trouve que ces deux phrases sont contradictoires:
1) il ne peut y avoir plusieurs commandes pour le même produit
2) à chaque fois que je modifie mon pro_stock, si le pro_stock est inférieur au pro_stock_alert, une ligne se crée dans ma table commander_article

comment veux-tu créer une ligne à chaque fois, et n'en avoir qu'une par produit?
Messages postés
54
Date d'inscription
samedi 3 avril 2021
Statut
Membre
Dernière intervention
8 mai 2021

Alors voilà le code que j'ai enfin réussi à corriger dans ma table 'commander_articles' , j'ai retiré le auto_increment mais aussi le primary key !! et cela a fonctionné. Et pour ta question c'était ce que je souhaité oui mais juste pour la seconde entrée.
La première update entrée comme la table 'commander_articles était vide l'ajout fonctionné mais c'était s'il on rentré une nouveau update par dessus ou ca bloqué a cause du primary key, il y en avais 2 celui de products également d'où le duplicata.

Ce que l'on veux c'est juste une alerte si le stock et inférieur au stock alerte on a juste en gros une table qui représente "produit" et une table qui représente une "alerte". Et oui il peux y avoir plusieurs commandes pour le même produit une erreur illogique de ma part désolé.

Voici le code corrigé

DROP TABLE IF EXISTS `commander_articles`;
CREATE TABLE IF NOT EXISTS `commander_articles` (
  `codart` INT(10) UNSIGNED NOT NULL,
  `qte` INT NOT NULL,
  `date` DATE NOT NULL,

 FOREIGN KEY(`codart`) REFERENCES `products`(`pro_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



Je t'invite à créer une ddb et rentré exactement mon code de tout en haut ensuite update les 3 requête dans l'ordre.
ps : pour le premier j'ai oublier where pro_id = .
Ensuite tu va voir qu'au 3eme update tu aura l'erreur.
Modifie juste la table `commander_articles` juste ici et tu verra ou je voulais en venir et quel était concrètement mon soucie expliqué n'est pas chose aisé.
MERCI.
Messages postés
15564
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
11 mai 2021
850
peux-tu alors marquer la discussion comme résolue?