Partage
  • Partager sur Facebook
  • Partager sur Twitter

Trigger Update validation de frais

MySQL, PhpMyAdmin, Appli lourde

Sujet résolu
    22 mai 2018 à 15:51:00

    Bonjour,

    Je suis en dernière année de BTS SIO et dans le cadre du projet de fin d'année, je dois faire une application lourde de validation de frais avec une base de donnée distante. 

    J'ai une base de donnée avec des valeurs de bases entrées par des demandeurs préalablement au traitement du trésorier, et des valeurs homologues avec le suffixe "_valid" pour les valeurs validées par le trésorier. (ex: le demandeur demande un remboursement de 200 euros sur le COUT_PEAGE, le trésorier n'en accepte que 150, la valeur de PEAGE_VALID est de 150. COUT_PEAGE reste à 200.).

    Un trigger nous est demandé, dans le cadre de mon sujet, j'ai pensé à un trigger qui permet que lorsque le trésorier valide les frais entrés par le demandeur sans les modifier; c'est-à-dire lorsque la valeur envoyée avec _valid est null; on copie directement depuis la base de donnée la valeur entrée préalablement par le demandeur dans la valeur _valid. (ex: le demandeur demande un remboursement de 100 euros sur le COUT_HEBERGEMENT, le trésorier valide sans modifier, la valeur de COUT_HEBERGEMENT est transmise à HEBERG_VALID. COUT_HEBERGEMENT = 100et HEBERG_VALID= 100.

    J'ai le trigger tel que

    BEGIN
    	UPDATE ligne_frais
        SET ligne_frais.PEAGE_VALID = ligne_frais.COUT_PEAGE
    	WHERE ligne_frais.ID_LIGNE = NEW.ID_LIGNE
        AND NEW.PEAGE_VALID = null;
    END


    Je teste avec l'UPDATE

    UPDATE `ligne_frais` SET `PEAGE_VALID`= null,`REPAS_VALID`=null,`HEBERG_VALID`= null,`KM_VALID`= null WHERE `ID_LIGNE`= 12

    Et j'obtiens une erreur 1442

    - Can't update table 'ligne_frais' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

    Quelqu'un pourrait m'aider ?

    (Je ne sais pas si j'ai assez bien détaillé, n'hésitez pas à me questionner si vous ne comprenez ce que je demande)

    • Partager sur Facebook
    • Partager sur Twitter
      22 mai 2018 à 16:31:12

      Bonjour,

      Tu ne peux pas faire un UPDATE de la table actuellement traitée par le TRIGGER sinon cela pourrait faire une boucle infinie ...

      Dans ton cas, il faut simplement SET les valeurs selon les conditions voulues ...

      BEGIN
      	IF NEW.PEAGE_VALID IS NULL THEN
      		SET NEW.PEAGE_VALID = NEW.COUT_PEAGE
      	END IF;
      END
      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        22 mai 2018 à 17:40:06

        L'autre solution consiste à passer par une Vue.

        Cette vue serait le reflet du contenu de la table. Comme il n'est pas possible de mettre à jour une vue directement, il faut de toute façon obligatoirement passer par des triggers. Ceux-ci manipulent la "vraie" table; il n'y a plus de risque de boucle.

        Syntaxe Postresql

        -- Création de la vue "miroir"
        CREATE OR REPLACE VIEW V_LIGNE_FRAIS as
        SELECT *
        FROM lignes_frais;
        
        -- Création d'une règle pour faire les insertions
        CREATE OR REPLACE RULE as R_I_V_LIGNE_FRAIS ON INSERT
          TO V_LIGNE_FRAIS
          DO INSTEAD (
            INSERT INTO lignes_frais VALUES NEW
          );
        
        -- Création d'une règle pour les suppressions
        CREATE OR REPLACE RULE as R_D_V_LIGNE_FRAIS ON DELETE
          TO V_LIGNE_FRAIS
          DO INSTEAD (
            DELETE FROM lignes_frais WHERE ID_LIGNE = OLD.ID_LIGNE
          );
        
        -- Création d'une règle pour les update, contenant un update personnalisé
        CREATE OR REPLACE RULE as R_U_V_LIGNE_FRAIS ON UPDATE
          TO V_LIGNE_FRAIS
          DO INSTEAD (
            UPDATE lignes_frais
              SET PEAGE_VALID = NEW.PEAGE_VALID,
                REPAS_VALID = EW.REPAS_VALID,
                ...
              WHERE ID_LIGNE = OLD.ID_LIGNE;
        
            UPDATE ligne_frais
              SET PEAGE_VALID = null,
                REPAS_VALID = null,
                HEBERG_VALID = null,
                KM_VALID = null
              WHERE ID_LIGNE = OLD.ID_LIGNE
                AND NEW.PEAGE_VALID IS NULL;
        
          );


        On peut alors faire toutes nos manipulations depuis le code à travers les vue, de manière entièrement transparente.

        C'est ici une bonne manière d'utiliser les vue : abstraire la complexité des données pour faciliter leurs utilisateur par les développeur.

        • Partager sur Facebook
        • Partager sur Twitter
          23 mai 2018 à 10:27:05

          Bonjour,

          Merci pour vos réponses, j'ai utilisé la première méthode de Benzouye car elle me suffisait, mais merci pour l'idée des vues aussi.

          Donc si ça peut aider quelqu'un, mon trigger final ressemble à ça :

          BEGIN
              IF NEW.HEBERG_VALID IS NULL THEN
                  SET NEW.HEBERG_VALID = NEW.COUT_HEBERGEMENT;
              END IF;
              IF NEW.PEAGE_VALID IS NULL THEN
                  SET NEW.PEAGE_VALID = NEW.COUT_PEAGE;
              END IF;
              IF NEW.REPAS_VALID IS NULL THEN
                  SET NEW.REPAS_VALID = NEW.COUT_REP;
              END IF;
              IF NEW.KM_VALID IS NULL THEN
                  SET NEW.KM_VALID = NEW.KM;
              END IF;
          END



          • Partager sur Facebook
          • Partager sur Twitter

          Trigger Update validation de frais

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown