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 / appel procedure / sql dynamique / bonnes pratiques


Sujet :

SQL Procédural MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 91
    Par défaut Trigger / appel procedure / sql dynamique / bonnes pratiques
    Bonjour,

    1/ Bonnes pratiques :
    Pour plus de visibilité dans le code d'un TRIGGER, je déclare un bon nombre
    de variables venant de la table mise à jour

    Ex. :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    DECLARE ROC_ID MEDIUMINT DEFAULT 0;
    DECLARE ROC_IS SMALLINT DEFAULT 1;
    DECLARE ROC_DS VARCHAR(8) DEFAULT '0';
    DECLARE ROC_DE VARCHAR(8) DEFAULT 0;
     
     
    SET ROC_ID=OLD.OC_0_ID;
    SET ROC_IS=OLD.IsValidated;
    SET ROC_DS=DATE_FORMAT(OLD.Date_starts, '%X%m%d');
    SET ROC_DE=DATE_FORMAT(OLD.Date_ends, '%X%m%d');
    Ceci est il a déconseillé par rapport aux performances de mySQL ?

    2/ J'ai lu que la SQL dynamique ou l'appel d'une procédure dans un trigger
    n'est pas possible

    -A- ai je bien compris ?

    -B- Un moyen de contourner cela ?
    Je m'explique : pour le calcul d'un prix d'un article, je fais appel
    à n paramètres qui selon leur valeur implique un traitement spécifique.

    Je me vois mal faire un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IF Param1=X AND Param2=Y [etc] THEN
    /*REQUETE*/
    END IF;
    Pour chaque jeu de valeurs des param...


    Merci

  2. #2
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 288
    Par défaut
    1/ je ne vois absolument pas l'intérêt... sans même parler de performance, je trouve que tu perds énormément de lisibilité au lieu d'en gagner.

    2/ Si mes souvenirs sont exacts, tu as le droit d'appeler une procédure dans un trigger, du moment que la procédure ne fait rien qui soit interdit au trigger... Plus généralement, même si tu appelais une procédure, je ne vois pas ce que tu pourrais en faire, car les procédures MySQL ne sont pas censées renvoyer de résultat.

    Dans ton cas, une fonction me semblerait plus adaptée.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 91
    Par défaut
    Bonjour Antoun

    Merci de vos réponses

    1/ Exact à l'usage c'est vraiment pas utile.

    2/ "Dans ton cas, une fonction me semblerait plus adaptée."
    Vous voulez dire :
    A- appeler la func dans le trigger
    B- remplacer le trigger par une func ?

    Mon pb au sein de ce trigger étant de crée dynamiquement
    une phrase sql excutée au sein de ce trigger

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Ex.,  du style :
    IF OLD.Level1_id>0 Then
    SQL_clause=CONCAT(' AND Level1_id=', OLD.Level1_id);
    END IF;
    Merci

  4. #4
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 288
    Par défaut
    Je pensais à une fonction dans un trigger, avec tous les if et autres dans la fonction (qui peut ainsi être appelée par plusieurs triggers, par exemple à la fois le ON INSERT et le ON UPDATE).

    Quant à ton idée d'utiliser du SQL dynamique (PREPARE / EXECUTE), je ne suis pas sûr que ce soit possible, et ce n'est pas une good practice quand ça peut être évité... si tu nous donnes la liste des cas que tu veux traiter, on peut t'aider à réécrire tout ça en SQL statique.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 91
    Par défaut
    Bonjour,

    0/ Merci de votre aide

    1/ Concernant le traitement des paramètres d'insertion des prix dans le trigger, c'est ok.
    J'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    IF OLD.Level1_ID>0 AND OLD.Level2_ID=0 AND OLD.LEVEL3_ID=0 THEN
    /*INSERT ... WHERE Level1_ID=OLD.Level1_id*/
    ELSEIF OLD.Level1_ID>0 AND OLD.Level2_ID>0 AND OLD.LEVEL3_ID=0 THEN
    /*INSERT ... WHERE Level2_ID=OLD.Level2_id*/
    ELSEIF OLD.Level1_ID>0 AND OLD.Level2_ID>0 AND OLD.LEVEL3_ID>0 THEN
    /*INSERT ... WHERE Level3_ID=OLD.Level3_id*/
    ELSE
    /*RIEN*/
    END IF;
    Puis pour le paramètre marque :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IF OLD.Brand_id>0 THEN
    /*DELETE ... WHERE OC_ID=OLD.OC_ID AND Brand_id<>OLD.Brand_id*/
    END IF;
    2/ Maintenant un autre pb se pose :
    La phrase SQL qui joint la table td_items et la table td_items_prices.
    Je m'explique :

    Un article a un prix "normal" (public_price)
    Un article peut avoir un prix "promo" (OC_ID=0, Discount_price)
    Un article peut avoir n prix en fonction des oc (OC_ID>0, Discount_price)

    Si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT 
    B.CODE, A.Discount_OC_ID
    , A.Public_price, A.Discount_price
    FROM td_items_parents_prices A INNER JOIN td_items_parents B ON A.Item_parent_ID=B.Item_parent_id
    WHERE A.Level1_id=5 AND A.Item_parent_ID=33
    J'obtiens :

    Code,Discount_oc_id,Public_price,Discount_price
    "ABC-1";"0";"260.000";"0" (prix public)
    "ABC-1";"0";"260.000";"130.000" (prix promo)
    "ABC-1";"117";"260.000";234.000"; (prix oc)

    Il me faut donc dédoublonner en récupérant les prix par priorité croissante, s'ils existent :
    Si Discount_oc_id=0 AND Discount_price>0 => Prix promo (priorité 1)
    Si Discount_oc_id>0 AND Discount_price>0 => Prix oc (priorité 2)
    Si Discount_oc_id=0 AND Discount_price=0 => Prix public (priorité 3)

    Le GROUP BY A.Item_parent_id, me dédoublonne bien les prix, mais
    ne me sort pas les prix par priorité.

    Un tips, une autre façon de faire svp ?
    Merci

  6. #6
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 288
    Par défaut
    Pour répondre déjà à ton 2/, si tes prix non-existant étaient NULL au lieu de 0, tu pourrais faire ça (je crois comprendre que l'arbitrage entre prix OC et prix promo est déjà fait) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    COALESCE(Discount_Price, Public_price)

    Si tu dois absolument garder tes zéros, ça donne :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    COALESCE(NULLIF(Discount_Price, 0), Public_price)

  7. #7
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 288
    Par défaut
    Pour ton 1/ maintenant, tu peux simplifier ton code en transformant les IF en WHERE dans ton INSERT :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    INSERT INTO ...
    SELECT ...
    WHERE Level1_ID=OLD.Level1_id and OLD.Level1_ID>0 AND OLD.Level2_ID=0 AND OLD.LEVEL3_ID=0
      OR Level2_ID=OLD.Level2_id and OLD.Level1_ID>0 AND OLD.Level2_ID>0 AND OLD.LEVEL3_ID=0
      OR Level3_ID=OLD.Level3_id and OLD.Level1_ID>0 AND OLD.Level2_ID>0 AND OLD.LEVEL3_ID>0
    Au passage, je ne comprends pas vraiment ce que veut dire WHERE Level1_ID=OLD.Level1_id dans tes INSERT ? Les trois insertions ont bien lieu sur la même table ?

    De même, pour ta gestion des marques, le IF peut se remplacer par un WHERE sur le DELETE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    DELETE ... 
    WHERE OLD.Brand_id>0 AND OC_ID=OLD.OC_ID AND Brand_id<>OLD.Brand_id

Discussions similaires

  1. Réponses: 4
    Dernier message: 21/07/2008, 20h39
  2. Trigger appelle procedure
    Par drzoidberg dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 27/05/2008, 10h28
  3. appel procedure sql server depuis oracle
    Par Jdubernat dans le forum Oracle
    Réponses: 2
    Dernier message: 21/12/2006, 15h43
  4. Réponses: 17
    Dernier message: 13/07/2006, 12h52
  5. Appel de function en SQL Dynamique
    Par dkd dans le forum Oracle
    Réponses: 22
    Dernier message: 28/09/2004, 18h01

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