Je crée une procédure stockée pour effectuer une recherche dans une table. J'ai de nombreux champs de recherche différents, tous facultatifs. Existe-t-il un moyen de créer une procédure stockée qui gérera cela? Disons que j'ai une table avec quatre champs: ID, FirstName, LastName et Title. Je pourrais faire quelque chose comme ça:
CREATE PROCEDURE spDoSearch
@FirstName varchar(25) = null,
@LastName varchar(25) = null,
@Title varchar(25) = null
AS
BEGIN
SELECT ID, FirstName, LastName, Title
FROM tblUsers
WHERE
FirstName = ISNULL(@FirstName, FirstName) AND
LastName = ISNULL(@LastName, LastName) AND
Title = ISNULL(@Title, Title)
END
Ce genre de travaux. Cependant, il ignore les enregistrements pour lesquels FirstName, LastName ou Title sont NULL. Si Title n'est pas spécifié dans les paramètres de recherche, je veux inclure les enregistrements où Title est NULL - idem pour FirstName et LastName. Je sais que je pourrais probablement le faire avec du SQL dynamique, mais j'aimerais éviter cela.
tsql
optional-parameters
Corey Burnett
la source
la source
code
where : ISNULL (FirstName, ') = ISNULL (@FirstName,' ') - cela fera de chaque NULL une chaîne vide et ceux-ci peuvent être comparés via eq. opérateur. Si vous voulez obtenir tous les titres si le paramètre d'entrée est nul, essayez quelque chose comme ça:code
FirstName = @FirstName OU @FirstName IS NULL.Réponses:
La modification dynamique des recherches basées sur les paramètres donnés est un sujet compliqué et le faire d'une manière plutôt que d'une autre, même avec seulement une très légère différence, peut avoir des implications énormes sur les performances. La clé est d'utiliser un index, d'ignorer le code compact, d'ignorer le souci de la répétition du code, vous devez faire un bon plan d'exécution de requête (utiliser un index).
Lisez ceci et considérez toutes les méthodes. Votre meilleure méthode dépendra de vos paramètres, de vos données, de votre schéma et de votre utilisation réelle:
Conditions de recherche dynamiques dans T-SQL par Erland Sommarskog
La malédiction et les bénédictions du SQL dynamique par Erland Sommarskog
Si vous disposez de la version appropriée de SQL Server 2008 (SQL 2008 SP1 CU5 (10.0.2746) et versions ultérieures), vous pouvez utiliser cette petite astuce pour utiliser réellement un index:
Ajoutez
OPTION (RECOMPILE)
à votre requête, consultez l'article d'Erland , et SQL Server résoudra leOR
de l'intérieur(@LastName IS NULL OR LastName= @LastName)
avant que le plan de requête ne soit créé en fonction des valeurs d'exécution des variables locales, et un index peut être utilisé.Cela fonctionnera pour n'importe quelle version de SQL Server (retourne des résultats corrects), mais n'inclut que OPTION (RECOMPILE) si vous utilisez SQL 2008 SP1 CU5 (10.0.2746) et versions ultérieures. L'OPTION (RECOMPILE) recompilera votre requête, seule la version répertoriée la recompilera en fonction des valeurs d'exécution actuelles des variables locales, ce qui vous donnera les meilleures performances. Si ce n'est pas sur cette version de SQL Server 2008, laissez simplement cette ligne désactivée.
la source
La réponse de @KM est bonne dans la mesure où elle disparaît, mais ne parvient pas à suivre pleinement l'un de ses premiers conseils;
Si vous cherchez à obtenir les meilleures performances, vous devez écrire une requête sur mesure pour chaque combinaison possible de critères facultatifs. Cela peut sembler extrême, et si vous avez beaucoup de critères facultatifs, cela peut l'être, mais les performances sont souvent un compromis entre l'effort et les résultats. En pratique, il peut y avoir un ensemble commun de combinaisons de paramètres qui peuvent être ciblées avec des requêtes sur mesure, puis une requête générique (comme pour les autres réponses) pour toutes les autres combinaisons.
L'avantage de cette approche est que, dans les cas courants traités par des requêtes sur mesure, la requête est aussi efficace que possible - il n'y a pas d'impact par les critères non fournis. En outre, les index et autres améliorations de performances peuvent être ciblés sur des requêtes spécifiques sur mesure plutôt que d'essayer de satisfaire toutes les situations possibles.
la source
Vous pouvez faire dans le cas suivant,
cependant dépendent des données parfois mieux créer des requêtes dynamiques et les exécuter.
la source
Cinq ans de retard à la fête.
Il est mentionné dans les liens fournis de la réponse acceptée, mais je pense qu'il mérite une réponse explicite sur SO - en construisant dynamiquement la requête en fonction des paramètres fournis. Par exemple:
Installer
Procédure
Usage
Avantages:
Les inconvénients:
Pas de réponse directe, mais lié au problème, c'est-à-dire la vue d'ensemble
Habituellement, ces procédures stockées de filtrage ne flottent pas, mais sont appelées à partir d'une couche de service. Cela laisse la possibilité de déplacer la logique métier (filtrage) de SQL vers la couche de service.
Un exemple utilise LINQ2SQL pour générer la requête en fonction des filtres fournis:
Avantages:
Les inconvénients:
la source
Prolongez votre
WHERE
condition:c'est-à-dire combiner différents cas avec des conditions booléennes.
la source
Cela fonctionne également:
la source