L'opérateur IN

L'opérateur SQL IN : Comment utiliser une liste d'éléments dans une requête

Date de publication : 30/07/2011. Date de mise à jour : 03/10/2011.

Par Fabrice Constans (http://loufab.developpez.com) (Blog)
 

L'opérateur IN, à la différence de LIKE, n'est disponible que pour SQL. Au vu de l'interaction de ce langage avec ACCESS, il peut vous rendre de précieux services et vous éviter des expressions à rallonge.

Commentez cet article : 11 commentaires

Viadeo Twitter Google Bookmarks ! Facebook Digg del.icio.us MySpace Yahoo MyWeb Blinklist Netvouz Reddit Simpy StumbleUpon Bookmarks Windows Live Favorites      



0. Introduction
I. La syntaxe
I-A. IN vs. =
II. En pratique
II-A. Zone liste, IN et état
II-A-1. Variante avec du texte
II-A-2. Variante avec des dates
III. Limitation
IV. Conclusion
V. Remerciement


0. Introduction

L'opérateur logique IN est un opérateur d'égalité strictement réservé à SQL. Il permet de déterminer si la valeur d'une expression est égale à l'une des valeurs comprises dans une liste donnée.

warning L'opérateur IN ne doit être confondu ni avec la clause de SQL qui détermine une source de données ni avec le mot clef VBA de la syntaxe For.

I. La syntaxe

La syntaxe est la suivante :
WHERE NomChamp IN (valeur1, valeur2, ... , valeurX )
La liste d'éléments à comparer est placée entre parenthèses.

On peut également trouver sa forme négative :
WHERE NomChamp NOT IN (valeur1, valeur2, ... , valeurX )
Il faut savoir que dans sa forme négative, il ne bénéficie pas de l'optimisation Rushmore. Pour en savoir plus sur la technologie Rushmore consultez le tutoriel sur l'optimisation des bases de données Microsoft Access.


On peut également utiliser une requête comme liste d'éléments à comparer, à condition que cette dernière ne renvoie qu'un champ.
SELECT * FROM TableA WHERE NomChamp IN (SELECT ChampId FROM TableB)
Cette forme de relation est intéressante par la souplesse de sa rédaction.


I-A. IN vs. =

Les exemples suivants démontrent l'avantage de l'opérateur IN.

Avec l'opérateur d'égalité la requête aura cette forme :
SELECT * FROM TableA WHERE champId = 1 or champId = 3 or champId = 10;
La même requête simplifiée grâce à l'opérateur IN :
SELECT * FROM TableA WHERE champId IN (1,3,10);

II. En pratique

Nous allons voir comment l'opérateur s'intègre parfaitement au fonctionnement d'une application pour créer des filtres à moindre coût.


II-A. Zone liste, IN et état

La zone de liste est un contrôle sympathique, encore faut-il pouvoir tirer parti de sa sélection multiple.

Pour la mise en pratique vous avez besoin d'une table contenant au moins un identifiant unique de type numérique et un champ de type texte.

Commencez par créer un formulaire composé d'une zone de liste et d'un bouton de commande.

La zone de liste doit être réglée de la manière suivante :

Nom Zliste
Nbre Colonnes 2
Largeurs colonnes 0 ;5
Contenu SELECT TCategorie.IdCategorie, TCategorie.Nom FROM TCategorie ORDER BY TCategorie.Nom;
Sélection Multiple Simple (ou Étendue)

Voici le résultat.


Créez ensuite un état nommé Test contenant les champs de cette même table. Peu importe la mise en page, c'est pour l'exemple.

Grâce à l'opérateur IN nous allons imprimer les éléments choisis dans la liste.

Dans l'événement Sur clic du bouton de commande insérez le code suivant :
Private Sub Commande2_Click()
Dim itm As Variant          ' l'item choisi
Dim lstval As String        ' la liste des id sélectionnés
For Each itm In Me.Zliste.ItemsSelected                 ' parcourt les items
    lstval = lstval & Me.Zliste.ItemData(itm) & ","     ' insère chaque id dans la variable
Next
lstval = Left(lstval, Len(lstval) - 1)                  ' supprime la dernière virgule
DoCmd.OpenReport "Test", acViewPreview, , "IdCategorie IN (" & lstval & ")"  ' imprime la sélection
End Sub
La méthode est simple, cependant elle ne gère pas l'erreur levée lorsqu'il n'y a pas de choix.

Sélectionnez quelques éléments et cliquez sur le bouton.


II-A-1. Variante avec du texte

La syntaxe est pratiquement identique à une différence près. Comme nous utilisons des éléments texte il faut utiliser le séparateur texte dans la liste de l'opérateur IN.

Changez la propriété de la liste :

Colonne Liée 2

Modifiez le code du bouton :
    lstval = lstval & """" & Me.Zliste.ItemData(itm) & ""","   ' insère chaque id dans la variable
Modifiez l'appel de l'état pour intégrer le nouveau nom de champ.
DoCmd.OpenReport "Test", acViewPreview, , "Nom IN (" & lstval & ")"  ' imprime la sélection
La syntaxe SQL sera donc :
WHERE NOM IN ("coiffeur","concerts" )

II-A-2. Variante avec des dates

Construisez un nouvel état avec cette source contenant une date et un champ texte. Indiquez la même source pour la zone de liste.

La ligne de construction de la liste change. Il faut mettre le symbole dièse (#) qui est le séparateur de dates et le format de date US.
    lstval = lstval & "#" & Format(Me.ZListe.ItemData(itm), "mm/dd/yyyy") & "#,"    ' insère chaque date 
warning Les dates dans VBA doivent toujours être au format anglo-saxon.
L'appel du formulaire change également pour utiliser le bon nom de champ.
DoCmd.OpenReport "Test2", acViewPreview, , "DateOperation IN (" & lstval & ")"  ' imprime la sélection
La syntaxe SQL sera donc :
WHERE DateOperation IN (#10/02/2011#,#12/12/2010#)

III. Limitation

Hormis le problème avec la forme négative de l'opérateur IN (Not IN) les limitations ne sont pas légion. En effet la liste peut compter plusieurs centaines d'éléments.

La valeur NULL doit être considérée avec précaution. Comparée à un élément de la liste elle peut produire des effets inattendus.

La liste est un ensemble de 1 à x éléments. On peut donc utiliser ce code quel que soit le nombre de sélections.


IV. Conclusion

Utiliser l'opérateur IN simplifie grandement la construction des requêtes SQL. Il évite de longs et complexes algorithmes de construction de clause WHERE ou HAVING et facilite l'écriture des requêtes de vérifications de clefs externes.


V. Remerciement

Je remercie Claude LELOUP pour ses corrections, ainsi que f_leb et philben pour leurs remarques.



               Version PDF (Miroir)   Version hors-ligne (Miroir)

Valid XHTML 1.0 TransitionalValid CSS!

Copyright © 2011 loufab. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC. Cette page est déposée.

 
 
 
 
Partenaires

Hébergement Web