Hello,

Le titre n'est p-e pas très clair alors voici quelques explications.

Toujours au sujet des promotions (à propos desquelles je vous sollicite depuis quelques temps), j'ai rédigé le trigger suivant :
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
 
CREATE TRIGGER [S_PROMO].[TRG_AFTER_INSERT_PDI] 
ON [S_PROMO].[T_PRODUCT_DEMO_IN_PDI] 
AFTER UPDATE AS 
BEGIN 
    SET NOCOUNT ON;  
 
    WITH T(PDI_BARCODE, PED_ID) AS (
        SELECT    INS.PDI_BARCODE,
                CASE
                    WHEN PED.PED_PERCENTAGE < PED2.PED_PERCENTAGE THEN PED.PED_ID
                    ELSE PED2.PED_ID
                END AS 'PED_ID'
        FROM    INSERTED INS
                    INNER JOIN S_PROMO.T_PRODUCT_DEMO_IN_PDI PDI
                        ON    INS.PDI_BARCODE = PDI.PDI_BARCODE
                        AND    INS.PED_ID <> PDI.PED_ID
                        INNER JOIN S_PROMO.T_PERCENTAGE_DEMO_PED PED
                            ON PDI.PED_ID = PED.PED_ID
                    INNER JOIN S_PROMO.T_PERCENTAGE_DEMO_PED PED2
                        ON    INS.PED_ID = PED2.PED_ID
        WHERE    PED.DTD_ID = PED2.DTD_ID)
 
    DELETE    S_PROMO.T_PRODUCT_DEMO_IN_PDI
    FROM    S_PROMO.T_PRODUCT_DEMO_IN_PDI PDI
                INNER JOIN T
                    ON    PDI.PED_ID = T.PED_ID
                    AND    PDI.PDI_BARCODE = T.PDI_BARCODE
 
END;
Au niveau des tables, pour que vous ayez une vision de leurs interactions cela s'organise comme ceci : (les colonnes en gras et soulignées sont les PK et les colonnes en italique sont les FK)

  • T_PROMO_PRM(PRM_ID, PRM_NAME, PRM_START, PRM_END) : table contenant le "header" de la promo. Ces infos vraiment spécifique quoi.
  • T_DETAIL_DEMO_DTD(DTD_ID, PRM_ID, CONT_ID) : table contenant les fournisseurs en démonstration qui participe à la promo (un fournisseur en démonstration est en fait un marchand qui loue un espace dans le magasin pour vendre sa marchandise. CONT_ID est la FK qui fait référence à la table des contrats avec ces fournisseurs)
  • T_PERCENTAGE_DEMO_PED(PED_ID, DTD_ID, PED_PERCENTAGE) : table contenant les pourcentages actifs pour chaque fournisseur démo)
  • T_PRODUCT_DEMO_IN_PDI(PED_ID, PDI_BARCODE) : table contenant les références des articles du fournisseurs démo qui participe à la promo. Si aucun article n'est présent dans cette table, alors la promo s'applique sur tous.


N.B. : Si certains préfèrent le code DDL de ces tables, suffit de demander. Mais il me semble que c'est plus clair ainsi sans avoir des colonnes supplémentaires non essentielles à la problématique qui viennent surcharger le tableau.
N.B.2 : Par souci de concision, je désignerai les tables par leur suffixe.

Maintenant, le pourquoi du trigger.
Si on ajoute dans PDI un article qui a déjà un autre pourcentage, je dois garder la ligne qui donne le plus grand pourcentage sur l'article en question.

Histoire de tester le trigger, j'ai rempli la table avec quelques références dans différents pourcentage pour un fournisseur X et j'ai fait ceci :
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
 
INSERT INTO S_PROMO.T_PRODUCT_DEMO_IN_PDI(PED_ID, PDI_BARCODE)
SELECT -2147479467,'3596488250893'
GO
 
WITH 
INSERTED(PED_ID, PDI_BARCODE) AS (
    SELECT -2147479467,'3596488250893'),
 T(PDI_BARCODE, PED_ID) AS (
    SELECT    INS.PDI_BARCODE,
            CASE
                WHEN PED.PED_PERCENTAGE < PED2.PED_PERCENTAGE THEN PED.PED_ID
                ELSE PED2.PED_ID
            END AS 'PED_ID'
    FROM    INSERTED INS
                INNER JOIN S_PROMO.T_PRODUCT_DEMO_IN_PDI PDI
                    ON    INS.PDI_BARCODE = PDI.PDI_BARCODE
                    AND    INS.PED_ID <> PDI.PED_ID
                    INNER JOIN S_PROMO.T_PERCENTAGE_DEMO_PED PED
                        ON PDI.PED_ID = PED.PED_ID
                INNER JOIN S_PROMO.T_PERCENTAGE_DEMO_PED PED2
                    ON    INS.PED_ID = PED2.PED_ID
    WHERE    PED.DTD_ID = PED2.DTD_ID)
 
    DELETE    S_PROMO.T_PRODUCT_DEMO_IN_PDI
    FROM    S_PROMO.T_PRODUCT_DEMO_IN_PDI PDI
                INNER JOIN T
                    ON    PDI.PED_ID = T.PED_ID
                    AND    PDI.PDI_BARCODE = T.PDI_BARCODE
J'insère donc une ligne et je simule ensuite la pseudo table INSERTED disponible dans le trigger via un CTE nommée INSERTED et j'y met une valeur. Si je ne fais pas d'erreur, on est donc dans la même situation que si on était vraiment dans le trigger non ?

Je crée alors une CTE nommée T qui contient le barcode et le PED_ID du pourcentage le plus faible pour les articles qui sont répertoriés dans plusieurs pourcentages pour un même fournisseur.
Finalement, je supprime de PDI les lignes qui matchent le contenu de T.

Et là, j'ai bien une ligne supprimée et il ne reste bien dans ma table qu'une seule fois cet article avec 60% (son autre pourcentage était de 50% donc le taff est bien fait).

Maintenant, lors de l'insertion de la ligne, pourquoi l'article à 50% n'est-il pas supprimé ? Appramment, le même code repris en dehors du trigger produit le resultat escompté. Du coup, je reste perplexe...

Des suggestions ?