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

Langage SQL Discussion :

Comment utiliser une clause IF dans une clause WHERE


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Septembre 2019
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Septembre 2019
    Messages : 27
    Points : 14
    Points
    14
    Par défaut Comment utiliser une clause IF dans une clause WHERE
    Bonjour à tous,

    Je fais appel aux bonnes âmes et les en remercie d'avance !

    Le contexte :

    J'ai encapsulé du code SQL dans un formulaire VBA (sous Excel).
    L'utilisateur du formulaire peut renseigner dans excel des variables, comme suit, avant exécution du formulaire :
    - une période (variables DD = date de début et DF = date de fin déclarées en tant que string) => ces 2 variables seront forcément renseignées
    - un n° de matricule (variable numérique déclarée en tant que Double)=> cette variable sera éventuellement renseignée.

    Mon problème :

    Je n'ai pas de résultat (sans bug) avec le code ci-dessous si la variable MATRIC n'est pas renseignée (mais OK si les 2 variables sont renseignées => données extraites pour la période et N° de matricule saisi)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    (...)
     
    requete = requete & " where date(vrhoromain) between " & DD & " and " & DF & " and r1matricul = " & MATRIC & "  "
     
    (...)

    J'ai tenté un CASE dans la clause WHERE mais ne marche pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    (...)
     
    requete = requete & " where Case when " & MATRIC & " = 0 then date(vrhoromain) between " & DD & " and " & DF & " "
     
    requete = requete & " Else date(vrhoromain) between " & DD & " and " & DF & " and r1matricul = " & MATRIC & " end "
     
    (...)
    Si quelqu'un d'entre vous a une idée, je suis grandement preneur.
    Merci

  2. #2
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    Bonjour,

    Si MATRIC n'est pas renseigné alors il faut gérer avec un COALESCE par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    requete = requete & " where date(vrhoromain) between " & DD & " and " & DF & " and r1matricul = coalesce(" & MATRIC & ",  r1matricul) "
    En plus je pense que ce serait mieux pour ces variables dans la clause WHERE d'être des variables liées plutôt que concaténées.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Septembre 2019
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Septembre 2019
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Bonjour Greg,

    Merci de ton retour.

    Je ne pense pas que le Coelesce va résoudre mon problème car cette fonction permet de retourner des valeurs numériques ou chaînes de caractères en remplacement de valeurs résultats NULL.

    Or dans mon cas, ce n'est pas la valeur retournée qui est NULL (le matricule étant un clé primaire obligatoire), mais une zone de saisie du formulaire (donnée d'entrée gérée en tant que variable) qui peut ne pas être renseignée.

    Dans ce cas, la requête me retourne aucun résultat alors qu'elle devrait me renvoyer tous les matricules concernés sur la période de temps saisie dans le formulaire.

  4. #4
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    Bonjour,

    Oui c'est bien le but du coalesce ici. Si &MATRIC n'est pas renseigné, alors on joint la colonne avec elle-même "r1matricul = r1matricul" pour que la requête retourne tous les matricules concernés.

  5. #5
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    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 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut vide n'est pas "null"
    Citation Envoyé par vanagreg Voir le message
    Bonjour,
    Oui c'est bien le but du coalesce ici. Si &MATRIC n'est pas renseigné, alors on joint la colonne avec elle-même "r1matricul = r1matricul" pour que la requête retourne tous les matricules concernés.

    Attention : il ne faut pas confondre un contenu chaîne de caractères vide et une colonne ayant le marqueur "null", ce n'est pas la même chose.
    La fonction COALESCE ne traite que les colonnes marquées NULL, pas les chaînes vides !

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    with tab(col1, col2) as
        (select 1, ''      union all
         select 2, null    union all
         select 3, 'ABC'   union all
         select 4, 'ZYX'   union all
         select 5, null    union all
         select 6, ''
        )
    select col1
         , col2
         , coalesce(col2, 'X')
    from tab
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    col1	col2	(No column name)
    1		
    2		X
    3	ABC	ABC
    4	ZYX	ZYX
    5		X
    6

  6. #6
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    En effet ça doit dépendre de la base de données mais dans Oracle chaine vide = null. Il suffit dans ce cas d'utiliser un CASE WHEN &MATRIC = ''.

  7. #7
    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 789
    Points
    30 789
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Attention : il ne faut pas confondre un contenu chaîne de caractères vide et une colonne ayant le marqueur "null", ce n'est pas la même chose.
    La fonction COALESCE ne traite que les colonnes marquées NULL, pas les chaînes vides !
    C'est vrai pour la grande majorité des SGBD à l'exception d'Oracle qui mélange allègrement chaîne vide et NULL
    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.

  8. #8
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    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 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par al1_24 Voir le message
    C'est vrai pour la grande majorité des SGBD à l'exception d'Oracle qui mélange allègrement chaîne vide et NULL
    dites moi pas que c'est pas vrai (Djamel Debbouze inside)

  9. #9
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par vanagreg Voir le message
    En effet ça doit dépendre de la base de données mais dans Oracle chaine vide = null. Il suffit dans ce cas d'utiliser un CASE WHEN &MATRIC = ''.
    Cela dépend du paramétrage d'oracle. Par défaut oui, car anciennement Oracle ne distinguait pas les deux....

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  10. #10
    Membre à l'essai
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Septembre 2019
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Septembre 2019
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Et sinon, pas d'idée quant à ma problématique ?

  11. #11
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2020
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2020
    Messages : 32
    Points : 96
    Points
    96
    Par défaut
    Pourquoi ne pas tester la valeur de MATRIC en amont dans le code VBA et adapter la requête en conséquence?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    requete = requete & " where date(vrhoromain) between " & DD & " and " & DF
    If MATRIC <>"" Then requete = requete & " and r1matricul = " & MATRIC

  12. #12
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2020
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2020
    Messages : 32
    Points : 96
    Points
    96
    Par défaut
    Par contre si les 3 variables sont des string bien penser à rajouter les quotes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    requete = requete & " where date(vrhoromain) between '" & DD & "' and '" & DF & "'"
    If MATRIC <>"" Then requete = requete & " and r1matricul = '" & MATRIC & "'"

  13. #13
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Cela dépend du paramétrage d'oracle. Par défaut oui, car anciennement Oracle ne distinguait pas les deux....

    A +
    C'est toujours le cas, avec une mise en garde:

    https://docs.oracle.com/en/database/...D-BCDBD5584071

    Note:
    Oracle Database currently treats a character value with a length of zero as null. However, this may not continue to be true in future releases, and Oracle recommends that you do not treat empty strings the same as nulls.
    C'est pour cela d'ailleurs qu'il y a des incohérences de comportements entre certaines fonctions. Par exemple concaténer une chaine de caractère CHAINE avec NULL ne donne pas NULL mais CHAINE, alors que RPAD ou LPAD sur NULL retourne NULL.

  14. #14
    Membre à l'essai
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Septembre 2019
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Septembre 2019
    Messages : 27
    Points : 14
    Points
    14
    Par défaut
    Merci Mavoune ! Ca marche impec modulo le remplacement de la valeur "" pour MATRIC par "0" car variable Double.
    Cela paraît tellement simple... Tu as raison, c'est tout aussi bien de tester la variable dans le code VBA.

    Bonne fin de journée et merci à tous

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 15/02/2019, 13h16
  2. Réponses: 2
    Dernier message: 02/05/2006, 14h34
  3. [Langage]Comment utiliser une dll .NET dans VB6?
    Par BouB dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 13/04/2006, 14h20
  4. Réponses: 4
    Dernier message: 16/02/2006, 16h28

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