Précédent   Forum des professionnels en informatique > Bases de données > MySQL > SQL Procédural
SQL Procédural Forum d'entraide sur les triggers, les procédures stockées et les fonctions en MySQL
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 26/07/2006, 19h18   #1
Membre actif
 
Inscription : juillet 2004
Messages : 277
Détails du profil
Informations forums :
Inscription : juillet 2004
Messages : 277
Points : 166
Points : 166
Par défaut Trigger et sum

J'ai 2 tables, l'une contient des quantité par stock, l'autre doit contenir la somme des quantités des stocks.

En fait, dans un cas, j'ai :
products, stock, quantité

dans l'autre table, j'ai :
products, quantitéTotale

Dans le premier cas, on à une quantité par stock, dans le second, c'est la somme des quantités par stock.

quantitéTotale = somme(quantité).

Je voudrais automatiser le calcul avec des triggers.
Cependant, je ne connais pas bien cette techno et j'ai beaucoup de mal à comprendre le fonctionnement, malgrès quelques explications sur developpez.com et autres.

J'ai essayé un code comme ça :
Code :
1
2
3
4
5
6
7
8
9
10
 
CREATE TRIGGER calcul_total AFTER UPDATE ON stock_warehouse
 FOR EACH ROW BEGIN
  DECLARE total INT(11);
  SELECT sum(sw.products_stock_quantity) AS tot
     INTO total 
     FROM stock_warehouse sw
     WHERE sw.products_stock_id = NEW.products_stock_id;
  UPDATE `products_stock` SET `products_stock_quantity` = total WHERE `products_stock_id` = NEW.products_stock_id ;
 END;
J'ai trouvé ces commandes sur des sites internet, mais ça n'a pas l'air de fonctionner avec MySQL.

Suis-je dans la bonne direction ou ai-je vraiment tout faux?
Pouvez-vous m'aider au moins a démarrer.
J'essaye de mettre dans total la somme de mes quantités qui sont dans stock_warehouse, puis de faire un UPDATE sur ma nouvelle table en mettant bien la quantité mise à jour.

Je suis un peu perdu avec ces triggers...

Merci!
__________________
Хајде Јано коло да играмо
SuperCed est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/07/2006, 20h08   #2
Rédacteur
 
Avatar de Biglo
 
Inscription : juillet 2002
Messages : 537
Détails du profil
Informations personnelles :
Localisation : France, Moselle (Lorraine)

Informations forums :
Inscription : juillet 2002
Messages : 537
Points : 561
Points : 561
Salut,

Je pense que c'est un très bon début. Ici tes totaux de stock seront mis à jour automatiquement quand il y a une mise à jour dans la table. Et je suppose que tu aimerais que ça le soit aussi après une insertion et une suppression. Il te faudra donc deux autres triggers.

Quant au calcul du nouveau total dans le cas d'un UPDATE, il y a plus simple selon moi :

Code :
UPDATE `products_stock` SET `products_stock_quantity` = `products_stock_quantity` - OLD.products_stock_quantity + NEW.products_stock_quantity WHERE `products_stock_id` = NEW.products_stock_id ;
Cela évite de faire un SELECT.

La syntaxe me semble correct pour MySQL, tu as sûrement eu un problème de delimiteur.
Code :
1
2
3
4
5
6
7
DELIMITER |
 
CREATE TRIGGER ...
 
END |
 
DELIMITER ;
Bonne continuation
Biglo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2006, 09h52   #3
Membre actif
 
Inscription : juillet 2004
Messages : 277
Détails du profil
Informations forums :
Inscription : juillet 2004
Messages : 277
Points : 166
Points : 166
Super, j'ai fait ça :
Code :
1
2
3
4
5
6
7
8
 
 
DELIMITER |
CREATE TRIGGER calcul_total AFTER UPDATE ON stock_warehouse
FOR EACH ROW BEGIN
    UPDATE `products_stock` SET `products_stock_quantity` = `products_stock_quantity` - OLD.products_stock_quantity + NEW.products_stock_quantity WHERE `products_stock_id` = NEW.products_stock_id ;
END |
DELIMITER ;
et ça a l'air de fonctionner! Maintenant, je vais en effet faire les modifs sur les insert et les delete.

Par contre, il est vrai que j'aurais préféré qu'il y ait un select avec un sum afin d'être certain d'avoir le bon résultat, même si c'est plus long.
En effet, dans le cas présent, si la quantité de la table products_stock est mise à jour directement et qu'il y a une erreur, on gardera toujours cette erreur quand on fera des UPDATE dans stock_warehouse.

Sinon, mon problème venait aussi du fait que j'essayais d'écrire mes trigger dans phpMyAdmin et que cela ne fonctionne pas. Il faut le faire directement en ligne de commande.

Merci beaucoup en tous cas!
__________________
Хајде Јано коло да играмо
SuperCed est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2006, 10h01   #4
Membre actif
 
Inscription : juillet 2004
Messages : 277
Détails du profil
Informations forums :
Inscription : juillet 2004
Messages : 277
Points : 166
Points : 166
J'ai fait ça direct dans MySQL :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
DELIMITER |
CREATE TRIGGER calcul_total AFTER UPDATE ON stock_warehouse
FOR EACH ROW BEGIN
    DECLARE total INT;
    SELECT sum(sw.products_stock_quantity) AS tot
     INTO total 
     FROM stock_warehouse sw
     WHERE sw.products_stock_id = NEW.products_stock_id;
     UPDATE `products_stock` SET `products_stock_quantity` = total WHERE `products_stock_id` = NEW.products_stock_id ;
END |
DELIMITER ;
Ca a l'air de fonctionner aussi. Par contre, je voudrais connaître un détail sur la ligne "DECLARE total INT;" Dans certain exexmples, ils mettent un "@" devant le total, je ne comprends pas à quoi ça sert.

Bon, je m'empresse de faire les version pour DELETE et INSERT.
Pour le INSERT, que deviennent les valeurs OLD.champ ? Et pour le DELETE, que devient NEW.champ?
__________________
Хајде Јано коло да играмо
SuperCed est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2006, 10h14   #5
Membre actif
 
Inscription : juillet 2004
Messages : 277
Détails du profil
Informations forums :
Inscription : juillet 2004
Messages : 277
Points : 166
Points : 166
J'ai fait ça finalement :
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
 
DELIMITER |
CREATE TRIGGER calcul_total_update AFTER UPDATE ON stock_warehouse
FOR EACH ROW BEGIN
    DECLARE total INT;
    SELECT sum(sw.products_stock_quantity) AS tot
     INTO total 
     FROM stock_warehouse sw
     WHERE sw.products_stock_id = NEW.products_stock_id;
     UPDATE `products_stock` SET `products_stock_quantity` = total WHERE `products_stock_id` = NEW.products_stock_id ;
END |
DELIMITER ;
 
DELIMITER |
CREATE TRIGGER calcul_total_insert AFTER INSERT ON stock_warehouse
FOR EACH ROW BEGIN
    DECLARE total INT;
    SELECT sum(sw.products_stock_quantity) AS tot
     INTO total 
     FROM stock_warehouse sw
     WHERE sw.products_stock_id = NEW.products_stock_id;
     UPDATE `products_stock` SET `products_stock_quantity` = total WHERE `products_stock_id` = NEW.products_stock_id ;
END |
DELIMITER ;
 
DELIMITER |
CREATE TRIGGER calcul_total_delete AFTER DELETE ON stock_warehouse
FOR EACH ROW BEGIN
    DECLARE total INT;
    SELECT sum(sw.products_stock_quantity) AS tot
     INTO total 
     FROM stock_warehouse sw
     WHERE sw.products_stock_id = OLD.products_stock_id;
     UPDATE `products_stock` SET `products_stock_quantity` = total WHERE `products_stock_id` = OLD.products_stock_id ;
END |
DELIMITER ;
Je suis étonné que ça fonctionne si bien aussi vite! Encore une bonne surprise de MySQL!
__________________
Хајде Јано коло да играмо
SuperCed est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2006, 10h46   #6
Rédacteur
 
Avatar de Biglo
 
Inscription : juillet 2002
Messages : 537
Détails du profil
Informations personnelles :
Localisation : France, Moselle (Lorraine)

Informations forums :
Inscription : juillet 2002
Messages : 537
Points : 561
Points : 561
Citation:
Envoyé par SuperCed
Ca a l'air de fonctionner aussi. Par contre, je voudrais connaître un détail sur la ligne "DECLARE total INT;" Dans certain exexmples, ils mettent un "@" devant le total, je ne comprends pas à quoi ça sert.
Dans un declare ? Le @ permet d'utiliser des variables définies par l'utilisateur qui ne sont pas limitées à une procédure : elles exisent tout au long de la connexion. Mais normalement, elles ne se déclarent pas dans une procédure.

Citation:
Envoyé par SuperCed
Pour le INSERT, que deviennent les valeurs OLD.champ ? Et pour le DELETE, que devient NEW.champ?
Je pense que tu as la réponse maintenant mais au cas où : INSERT => il n'y a pas de OLD et DELETE => pas de NEW

Si tu veux garder absolument ton select pour calculer le total, tu peux faire une fonction (create function) qui prend en paramètre l'identifiant du stock et qui retourne le total de ce stock. Ca sera un peu plus propre, et aussi une occasion d'essayer les fonctions si tu ne l'as jamais fait.
Biglo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2006, 11h20   #7
Membre actif
 
Inscription : juillet 2004
Messages : 277
Détails du profil
Informations forums :
Inscription : juillet 2004
Messages : 277
Points : 166
Points : 166
Ok, merci beaucoup.

Il faudra que je teste les fonctions en effet.

Sinon, j'aimerais en savoir un peu plus sur les triggers, et plus particulièrement ou ils sont stockés dans MySQL. C'est juste à titre informatif. C'est utile de savoir ça si je veux exporter ma base de données.
__________________
Хајде Јано коло да играмо
SuperCed est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2006, 14h17   #8
Rédacteur
 
Avatar de Biglo
 
Inscription : juillet 2002
Messages : 537
Détails du profil
Informations personnelles :
Localisation : France, Moselle (Lorraine)

Informations forums :
Inscription : juillet 2002
Messages : 537
Points : 561
Points : 561
Salut,

Les triggers sont associés aux tables qu'ils concernent, contrairement aux procédures et fonctions qui sont associées à une base. Cependant, je ne sais pas te dire où ils sont stockés.

Pour la sauvegarde, le programme mysqldump permet également de dumper les triggers avec l'option --triggers.
Biglo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2006, 14h40   #9
Membre actif
 
Inscription : juillet 2004
Messages : 277
Détails du profil
Informations forums :
Inscription : juillet 2004
Messages : 277
Points : 166
Points : 166
Super merci!

J'ai tout ce qu'il me faut!
__________________
Хајде Јано коло да играмо
SuperCed 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 12h05.


 
 
 
 
Partenaires

Hébergement Web