Les systèmes modernes de BI et CRM nécessitent souvent de mettre en œuvre des filtres utilisateur : il est essentiel de combiner de manière flexible des conditions arbitraires (par date, sexe, statut, tags) et de les croiser et de les combiner correctement dans le langage SQL. Le code résultant doit être lisible, facilement modifiable et produire un résultat attendu.
Souvent, les développeurs forment "à la volée" des WHERE avec de nombreux AND/OR à partir de filtres utilisateur, ce qui entraîne des erreurs logiques et des requêtes difficiles à maintenir. Le problème est aggravé si les valeurs des filtres peuvent être absentes ou combinées avec IN/EXISTS/LIKE.
Pour les filtres dynamiques, un modèle pratique est "la condition avec OR est toujours TRUE si la valeur n’est pas fournie" :
SELECT * FROM users WHERE (status = @status OR @status IS NULL) AND (gender = @gender OR @gender IS NULL) AND (created >= @from_date OR @from_date IS NULL) AND (city IN (@cities) OR @cities IS NULL);
Ou en utilisant SQL dynamique :
DECLARE @sql NVARCHAR(MAX) = N'SELECT * FROM users WHERE 1=1'; IF @status IS NOT NULL SET @sql += N' AND status = @status'; IF @gender IS NOT NULL SET @sql += N' AND gender = @gender'; -- ... EXEC sp_executesql @sql, N'@status NVARCHAR(10),@gender NVARCHAR(10)', @status, @gender;
Caractéristiques clés :
Peut-on utiliser WHERE 1=1 partout au lieu de vérifier la présence des conditions ?
Non, 1=1 est seulement une condition de démarrage pour la concaténation de WHERE – elle ne remplace pas les filtres mais est utilisée uniquement pour la commodité de génération des requêtes.
Quels problèmes peuvent survenir si une liste vide est incluse dans IN () ?
IN (NULL) ou IN () retourne toujours false et produit un ensemble vide, même en l'absence de filtre. Pour un bon fonctionnement, il convient de vérifier distinctement si la liste est vide et de ne pas inclure la condition.
Comment de tels constructeurs affecteront-ils l'utilisation des index et la performance ?
Si les filtres sont réalisés avec OR ou des vérifications NULL, de nombreux SGBD cesseront d'utiliser efficacement les index ou exécuteront un scan de toute la table. Il est préférable d'appliquer des approches avec SQL dynamique ou des filtres via des requêtes paramétrées pour que le planificateur puisse choisir un index.
Un rapport classique avec 10 filtres, le code forme WHERE avec de nombreux OR — en l'absence de plusieurs filtres, le résultat revient à un ensemble vide ou à un scan trop important, la charge sur le serveur augmente considérablement.
Avantages :
Une fonction distincte forme des filtres uniquement selon les paramètres fournis, et pour chaque groupe de conditions, un JOIN/FILTER distinct est inclus. Where ne contient pas de OR et de vérifications superflues sur NULL.
Avantages :