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 :

Plusieurs IF pour différentes sélections conditionnelles dans un déclencheur [MySQL-5.7]


Sujet :

SQL Procédural MySQL

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2019
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Plusieurs IF pour différentes sélections conditionnelles dans un déclencheur
    <config>Windows / Opera Next 60.0.3255.95 / Mysql</config>

    J'ai un problème lorsque j'essaie de calculer le nombre de lignes dans ma table, en utilisant des conditions ifs multiples séparées dans un déclencheur pour tester si le champ s'il est vide ou pas.

    J'ai essayé de mettre le si hors de la fonction de sélection et cela fonctionne mais je ne peux pas le faire pour tous les cas possible que j'ai, ce ne sera pas optimisé.

    voila le code à l'intérieur du déclencheur :

    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
    UPDATE max_tare
    SET max_row = (SELECT COUNT(*)FROM history 
                                  IF(NEW.client != '') THEN
                                  WHERE nom LIKE CONCAT('%', NEW.client, '%') END IF;
                                  IF(NEW.commune != '') THEN
                                  WHERE commune LIKE CONCAT('%', NEW.commune, '%') END IF;
                                  IF(NEW.type != '') THEN
                                  WHERE type LIKE CONCAT('%', NEW.type, '%') END IF;
                                  IF(NEW.matricule != '') THEN
                                  WHERE mat LIKE CONCAT('%', NEW.matricule, '%') END IF;
                                  IF(NEW.tare != '') THEN
                                  WHERE tare LIKE CONCAT('%', NEW.tare, '%') END IF;
                                  WHERE cancled = 0), 
    max_tare = (SELECT SUM(tare)  FROM history
                                                WHERE cancled = 0) WHERE id = 1;
    L'erreur me renvois vers une erreur de syntaxe tels que suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MySQL a répondu: # 1064 - Erreur de syntaxe près de 'IF' (new.client! = '') THEN WHERE nom LIKE CONCAT ('%', NEW.client, '%') END IF;
    voila tout d'abord j'ai pensé que c'est une histoire de délimiter j'ai essayer d'éditer en ligne et de changer de delimiter mais toujours c'est le même problème apres tout c'est peut être ma méthode d'insertion de delimiter qui est fausse, car je suis un débutant novice en sql

    mais en tout cas je sais que le solution elle existe, car quand je travaille en query sous php en utilisant le framework codeigniter en utilisant ce code la :
    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
    $this->db->select("*");
     
    $this->db->from('history');
     
    if ($query[1] != '') {
        $this->db->like('nom', $query[1]);
                    }
    if ($query[2] != '') {
        $this->db->like('commune', $query[2]);
                    }
    if ($query[3] != '') {
        $this->db->like('type', $query[3]);
                    }
    if ($query[4] != '') {
        $this->db->like('mat', $query[4]);
                    }
    if ($query[10] != '') {
        $this->db->like('rfid', $query[10]);
                    }
    if ($query[5] != '') {
        $this->db->like('tare', $query[5]);
                    }
    if ($query[6] != '') {
        $this->db->where('date >', $query[6]);
                    }
    if ($query[7] != '') {
        $this->db->where('date <', $query[7]);
                    }
    if ($query[11] != '') {
        $this->db->where('time_plode >', $query[11]);
                    }
    if ($query[12] != '') {
        $this->db->where('time_plode <', $query[12]);
                    }
    $this->db->where('cancled', 0);
    return $this->db->count_all_results();
    biensure ce code récupéré que le nombre total des lignes et non pas la somme mais ce n'est pas soucis j'ai juste mise une partie car c'est le même code sauf que je change la fonction d'interrogation de la base de donnée.

    le seul soucis avec php c'est que les requête prenne beaucoup de temps a s'exécute, et c'est pour cela je voulais un déclencheur (triggers) pour faire les chose en arrière plan.

    bon afin de rapprocher mieux l'idée de ce que je veux exactement je vais vous faire un exemple :

    ça c'est ma table history au quel je veux compter les lignes ayant cancled égal a 0 et répond au champ du filtre.

    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
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    |                                         history                                |
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    | id | nom         | commune | type   | mat          | tare  | rfid    | cancled |
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    | 1  | EPIC paris  | france  | white  | 01248-816-16 | 7600  | ABCF44C | 0       |
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    | 2  | EPIC london | UK      | white  | 06854-315-16 | 5233  | A8CG27C | 1       |
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    | 3  | NET barça   | ESP     | red    | 03254-615-16 | 8900  | HBC54AC | 1       |
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    | 4  | NET Dubai   | arab    | blue   | 35251-117-16 | 11200 | HDK7BV5 | 0       |
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    | 5  | EPIC roma   | ita     | red    | 36524-618-16 | 7300  | NBL53DC | 0       |
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    | 6  | SNC beta    | alpha   | green  | 69358-117-16 | 5400  | JDLF8ND | 1       |
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    | 7  | EPIC tokyo  | japan   | yellow | 46258-712-16 | 8700  | K5ND55D | 1       |
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    | 8  | SARL Fit    | body    | black  | 69531-614-16 | 9600  | AIES5HJ | 0       |
    +----+-------------+---------+--------+--------------+-------+---------+---------+
    voila mon tableau qui contient mon filtre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    +----+--------+---------+------+--------------+------+
    |                     temp_fetch                     |
    +----+--------+---------+------+--------------+------+
    | id | client | commune | type | matricule    | tare |
    +----+--------+---------+------+--------------+------+
    | 1  | EPIC   |         |      |              |      |
    +----+--------+---------+------+--------------+------+
    en choisissant le mot "EPIC" qui dois figurer dans les lignes contenants EPIC dans leur nom et aussi ayant cancled = 0 mon résultat devrais être comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    +----------------------------+
    |          max_tare          |
    +----------------------------+
    | id |  max_row   | max_tare |
    +----+------------+----------+
    | 1  |     2      | 14900    |
    +----+------------+----------+
    voila j'ai essayé plein d'exemple et de solution sans aboutir a un résultat concret, tout au moins il y'a une solution Archaïque, c'est de faire sortir les a l'extérieur, et faire un select from pour chaque cas obtenu, en d'autre mot :
    <code>si (client !=0 et commune ==0 et type == 0 et matricule == 0 et tare == 0) alors
    {filtrer selon client seulement }
    sinon-si (client !=0 et commune !=0 et type == 0 et matricule == 0 et tare == 0) alors
    {filtrer selon client et commune seulement }....ect </code>
    malheureusement pour moi je ne peux appeler cela comme solutions, car si je veux modifier ou rajouter un champs a mon filtre c'est tout le code se change.
    Merci d'avance pour votre aide je reste disponible si vous voulez plus de clarification.

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Vous ne pouvez pas coder la requête de cette façon, remplacez par des conditions comme ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    update  matable1
    set ma_col1 =
       (select sum(case when Col1=01 and Col2 ='AA' then 1
                        when Col1=02 and Col2<>'AA' then 1
                        else 0
                   end)
        from matable2
        where)
      , ma_col2 = etc...

  3. #3
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Regarde ta condition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IF(NEW.client != '') THEN
                                  WHERE nom LIKE CONCAT('%', NEW.client, '%') END IF;
    Que devient-elle quand NEW.client = '' ?
    nom LIKE CONCAT('%', '', '%') ou plus simplement nom LIKE '%%' qui est toujours vérifié !

    Tu n'as donc pas besoin de tester la valeur de NEW.client !
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  4. #4
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2019
    Messages : 4
    Points : 3
    Points
    3
    Par défaut case statement
    Citation Envoyé par escartefigue Voir le message
    Vous ne pouvez pas coder la requête de cette façon, remplacez par des conditions comme ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    update  matable1
    set ma_col1 =
       (select sum(case when Col1=01 and Col2 ='AA' then 1
                        when Col1=02 and Col2<>'AA' then 1
                        else 0
                   end)
        from matable2
        where)
      , ma_col2 = etc...
    yes this will probably work but i have to taste all cases ased on if they are empty or not :'(

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2019
    Messages : 4
    Points : 3
    Points
    3
    Par défaut if i dont use -if conditions-
    Citation Envoyé par al1_24 Voir le message
    Regarde ta condition :

    Que devient-elle quand NEW.client = '' ?
    nom LIKE CONCAT('%', '', '%') ou plus simplement nom LIKE '%%' qui est toujours vérifié !

    Tu n'as donc pas besoin de tester la valeur de NEW.client !
    oui mais nom LIKE '%%' ne me renvois aucun resultat, dire que c'est toujours verifié j'ai deja essayé ce code
    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
    BEGIN
    UPDATE max_tare
    SET max_row = (
    SELECT COUNT(*)
    FROM history 
    WHERE cancled = 0
     AND nom LIKE CONCAT('%', NEW.client, '%')
     AND commune LIKE CONCAT('%', NEW.commune, '%')
     AND type LIKE CONCAT('%', NEW.type, '%')
     AND mat  LIKE CONCAT('%', NEW.matricule, '%')
     AND tare LIKE CONCAT('%', NEW.tare, '%')
     AND rfid LIKE CONCAT('%', NEW.rfid, '%')), 
     
    max_tare =
        (SELECT SUM(tare)
         FROM history
         WHERE cancled = 0) WHERE id = 1;
     
     
     
    END
    et ça renvois 0 ligne et quand j'ai inversé les and en OR ça fait multiplier le résultat

  6. #6
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Citation Envoyé par hakushakusama Voir le message
    oui mais nom LIKE '%%' ne me renvoie aucun résultat, dire que c'est toujours vérifié j'ai déjà essayé ce code
    Un problème avec les NULL ?
    Que donne COALESCE(nom, '') LIKE CONCAT('%', COALESCE(NEW.client, ''), '%') ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2019
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Citation Envoyé par al1_24 Voir le message
    Un problème avec les NULL ?
    Que donne COALESCE(nom, '') LIKE CONCAT('%', COALESCE(NEW.client, ''), '%') ?
    c'est la solution ça marche parfaitement, merci beaucoup...

  8. #8
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut hakushakusama.

    1) vous faites des "like" en utilisant le caractère '%' :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE nom LIKE CONCAT('%', NEW.client, '%')
    Je comprends parfaitement ce que vous cherchez à faire, mais coté performance, le résultat sera déplorable.
    Il est inutile de mettre des index car vos colonnes sont non sargables.

    Si je reprends votre exemple avec la chaîne "EPIC", il faudrait, toujours pour des raisons de performances, utiliser les "Full-Text Search".
    --> https://dev.mysql.com/doc/refman/8.0...xt-search.html

    Ou bien utiliser des clefs étrangères afin de relier ce que vous cherchez avec votre table "temp_fetch".

    2) votre requête est mal foutu.
    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
     
     UPDATE `max_tare`
        SET max_row  = (  SELECT  sum(  CASE WHEN coalesce(NEW.client,    '') <> '' THEN 1
                                             WHEN coalesce(NEW.commune,   '') <> '' THEN 1
                                             WHEN coalesce(NEW.type,      '') <> '' THEN 1
                                             WHEN coalesce(NEW.matricule, '') <> '' THEN 1
                                             WHEN coalesce(NEW.tare,      '') <> '' THEN 1
                                                                                    ELSE 0 END
                                    )
                            FROM  `history`
                           WHERE  cancled = 0
                                      ),
            max_tare = (  SELECT  sum(tare)
                            FROM  `history`
                           WHERE  cancled = 0
                       )
    WHERE id = 1;
    3) vous devriez revoir votre modèle conceptuel de données afin de mieux gérer vos totaux.
    Est-ce bien utile de stocker ce genre d'information ? Une view ferait aussi bien l'affaire !

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 28/10/2016, 10h44
  2. Plusieurs scripts pour différents groups par GPO
    Par spike93 dans le forum Windows Serveur
    Réponses: 3
    Dernier message: 02/03/2010, 10h02
  3. [XL-2007] plusieurs Controls pour différente liste de textbox
    Par north_ dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 04/08/2009, 07h00
  4. Réponses: 1
    Dernier message: 03/07/2009, 15h51

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