IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Procédural MySQL Discussion :

Trigger et sum


Sujet :

SQL Procédural MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Ingénieur développement
    Inscrit en
    Juillet 2004
    Messages
    323
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement

    Informations forums :
    Inscription : Juillet 2004
    Messages : 323
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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!

  2. #2
    Membre émérite
    Avatar de Biglo
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 537
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    DELIMITER |
     
    CREATE TRIGGER ...
     
    END |
     
    DELIMITER ;
    Bonne continuation

  3. #3
    Membre éclairé
    Profil pro
    Ingénieur développement
    Inscrit en
    Juillet 2004
    Messages
    323
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement

    Informations forums :
    Inscription : Juillet 2004
    Messages : 323
    Par défaut
    Super, j'ai fait ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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!

  4. #4
    Membre éclairé
    Profil pro
    Ingénieur développement
    Inscrit en
    Juillet 2004
    Messages
    323
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement

    Informations forums :
    Inscription : Juillet 2004
    Messages : 323
    Par défaut
    J'ai fait ça direct dans MySQL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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?

  5. #5
    Membre éclairé
    Profil pro
    Ingénieur développement
    Inscrit en
    Juillet 2004
    Messages
    323
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement

    Informations forums :
    Inscription : Juillet 2004
    Messages : 323
    Par défaut
    J'ai fait ça finalement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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!

  6. #6
    Membre émérite
    Avatar de Biglo
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 537
    Par défaut
    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.

  7. #7
    Membre éclairé
    Profil pro
    Ingénieur développement
    Inscrit en
    Juillet 2004
    Messages
    323
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement

    Informations forums :
    Inscription : Juillet 2004
    Messages : 323
    Par défaut
    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.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Bloqué sur 1 Trigger avec utilisation de SUM
    Par lolymeupy dans le forum Développement
    Réponses: 1
    Dernier message: 07/11/2008, 13h49
  2. [power designer et Sybase] trigger
    Par mr_qno dans le forum Sybase
    Réponses: 4
    Dernier message: 12/07/2006, 18h32
  3. [PostgreSQL] Refus de STATEMENT dans un trigger
    Par alex2205 dans le forum Requêtes
    Réponses: 3
    Dernier message: 10/03/2003, 12h51
  4. [VBA-E] Fonction sum() dans une cellule
    Par Gonzo dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 16/12/2002, 10h18
  5. [Comparatif] Procédures stockées, triggers, etc.
    Par MCZz dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 28/08/2002, 12h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo