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

MS SQL Server Discussion :

CASE dans un WHERE avec un IN()


Sujet :

MS SQL Server

  1. #1
    Membre actif Avatar de seb.49
    Profil pro
    ljgdfgdf
    Inscrit en
    Octobre 2002
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : ljgdfgdf

    Informations forums :
    Inscription : Octobre 2002
    Messages : 291
    Points : 209
    Points
    209
    Par défaut CASE dans un WHERE avec un IN()
    Bonjour,

    Dans une procédure stockée, je voudrais selon qu'un parametre est renseigné ou non que la clause WHERE s'adapte sachant que la clause WHERE contient un IN

    J'ai trouvé une fonction qui transforme une chaine en une liste utilisable dans un IN.
    L'adresse de la fonction est ici : http://www.devx.com/tips/Tip/20009
    La fonction s'appelle dbo.UTILfn_Split

    Voici la requete "à ma facon" qui ne marche pas mais qui se rapproche le plus du succès je crois.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT * from MATABLE
    WHERE 
    CHAMPID IN (
    Case 
              When 1=1 then ((select value from dbo.UTILfn_Split ('11,12', ',')))
              else CHAMPID
        end)
    Le problème est le message
    La sous-requête a retourné plusieurs valeurs. Cela n'est pas autorisé quand la sous-requête suit =, !=, <, <= , >, >= ou quand elle est utilisée en tant qu'expression.
    Bref, je suis bloqué. Merci de votre aide

  2. #2
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 674
    Points
    1 674
    Billets dans le blog
    8
    Par défaut
    Tu peux essayer cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * 
    FROM MATABLE
    WHERE CHAMPID IN (SELECT value FROM dbo.UTILfn_Split ('11,12', ','))
    A+

  3. #3
    Membre actif Avatar de seb.49
    Profil pro
    ljgdfgdf
    Inscrit en
    Octobre 2002
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : ljgdfgdf

    Informations forums :
    Inscription : Octobre 2002
    Messages : 291
    Points : 209
    Points
    209
    Par défaut
    Ce n'est pas suffisant.
    Dans mon exemple (revu)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT * FROM MATABLE
    WHERE 
    CHAMPID IN (
    Case 
              When @Param then ((SELECT value FROM dbo.UTILfn_Split (@Param ',')))
              else CHAMPID
        end)      
    --param étant une chaine de caractère passé à la procédure stockée
    • Si le parametre est vide, alors je ne veux pas faire de where ou alors tout récupérer
    • Le champ ID est un entier
    • J'aurais bcp d'autre critère ensuite à ajouter

  4. #4
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Pour faire le :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE CHAMPID IN ( @Param )
    on peut éventuellement exécuter une requête dynamique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    DECLARE @query VARCHAR(MAX) = 
      'SELECT * FROM MATABLE'
      +
      CASE WHEN @Param IS NOT NULL
      THEN ' WHERE CHAMPID IN (' + @Param +')'
      ELSE ''
      END
     
    EXEC (@query)
    C'est plus rapide que d'utiliser la fonction dbo.UTILfn_Split, mais c'est pas très propre.

    Pour passer des listes d'arguments, j'aime bien utiliser une variable XML, par exemple (voir: OPENXML (T-SQL) ).

  5. #5
    Membre actif Avatar de seb.49
    Profil pro
    ljgdfgdf
    Inscrit en
    Octobre 2002
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : ljgdfgdf

    Informations forums :
    Inscription : Octobre 2002
    Messages : 291
    Points : 209
    Points
    209
    Par défaut
    Merci pour cette réponse,

    En effet, la requete dynamique n'est pas propre et ca perd tout l'intérêt des procédures stockées a savoir la mise en cache du plan d'exécution.

    Vous auriez un exemple du XML dans un IN? Merci

  6. #6
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Citation Envoyé par seb.49 Voir le message
    Vous auriez un exemple du XML dans un IN? Merci

    Pas tout prêt sous la main, mais en gros :
    • on déclare une table temporaire
    • dans cette table temporaire on met le contenu de la variable XML (sp_xml_preparedocument, OPENXML, sp_xml_removedocument)
    • on utilise la table temporaire dans une requête
    Pour le deuxième point, il faut s'inspirer des exemples de la page OPENXML (T-SQL)

  7. #7
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 674
    Points
    1 674
    Billets dans le blog
    8
    Par défaut
    Tu n’étais pas assez précis dans ton premier post

    Ci-dessous la requête répondant à ta demande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT * 
    FROM MATABLE
    WHERE  ( (CHAMPID IN (SELECT cast(value as int) 
                          FROM dbo.UTILfn_Split (@Param, ',')) ) 
             OR (ISNULL(@Param,'') = '')
          )
    -- AND .... (autres critères)
    Remarque : En terme de performance, cela a été démontré, ce " bricolage" est beaucoup moins performant que la construction dynamique d’une requête.
    En effet, vouloir traiter tout les cas possibles dans une clause WHERE, l’optimiseur finit par établir un plan d’exécution moins performant, parfois même catastrophique avec des full scan sur les tables etc..
    Conclusion : Dans ce genre de situation préférez l’utilisation du sql dynamique
    EXEC sp_executesql

    A+

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

Discussions similaires

  1. Procédure stockée : clause CASE dans mon WHERE ?
    Par ridokou dans le forum Développement
    Réponses: 5
    Dernier message: 27/05/2011, 14h55
  2. utilisation d'un case dans un where
    Par stephyugh dans le forum Langage SQL
    Réponses: 3
    Dernier message: 31/10/2007, 18h31
  3. un CASE dans un WHERE...
    Par nox75 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 27/09/2007, 15h47
  4. Problème de syntaxe d'un CASE dans un WHERE?
    Par Danny Blue dans le forum Langage SQL
    Réponses: 4
    Dernier message: 06/04/2007, 00h18
  5. [t-sql] instruction CASE dans clause WHERE
    Par ignitionflip dans le forum Langage SQL
    Réponses: 4
    Dernier message: 22/01/2007, 19h07

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