J'ai un écran de recherche sur lequel l'utilisateur peut spécifier n'importe quelle combinaison de prénom, nom, semestre ou cours. Je ne sais pas comment coder de façon optimale la procédure stockée SQL Server 2005 pour gérer ces paramètres potentiellement facultatifs. Quel est le moyen le plus efficace? Procédures distinctes pour chaque combinaison? Prendre les éléments comme des valeurs nulles et construire un SQL dynamique?Codage de la procédure stockée pour l'écran de recherche avec plusieurs critères optionnels
Répondre
La meilleure solution consiste à utiliser sp_execute_sql. Par exemple:
--BEGIN SQL
declare @sql nvarchar(4000)
set @sql =
'select * from weblogs.dbo.vwlogs
where Log_time between @BeginDate and @EndDate'
+ case when @UserName is null then '' else 'and client_user = @UserName' end
sp_execute_sql
@sql
, @params = '@UserName varchar(50)'
, @UserName = @UserName
--END SQL
Comme mentionné muerte, cela aura un avantage de performance par rapport à exec() 'ing une déclaration similaire.
Je le ferais avec sp_executesql parce que le plan sera mis en cache juste pour le premier modèle, ou le premier ensemble de conditions.
Jetez un oeil à ce TechNet article:
sp_executesql peut être utilisé à la place des procédures stockées pour exécuter une instruction Transact-SQL à plusieurs reprises lorsque le changement des valeurs de paramètre à l'instruction est la seule variation. Étant donné que l'instruction Transact-SQL elle-même reste constante et que seules les valeurs de paramètre changent, l'optimiseur de requête SQL Server est susceptible de réutiliser le plan d'exécution qu'il génère pour la première exécution.
Si vous utilisez sp_executesql, vous devez vous assurer que vous n'introduisez aucun problème d'injection SQL. –
Donc, votre réponse est "dynamique SQL" alors. –
Pas nécessairement - la question était pour la solution de procédure stockée, et il pourrait y avoir une logique supplémentaire avant sp_executesql. Bottom line, la vraie réponse est que l'on devrait essayer d'éviter de vérifier les valeurs NULL pour chaque paramètre, au moins pour des raisons de performance. – muerte
Je mets chaque paramètre à option (valeur par défaut étant null)
puis la Abordez la OU ....
FirstName=ISNULL(@FirstName,FirstName)
AND
LastName=ISNULL(@LastName,LastName)
AND
SemesterID=ISNULL(@SemesterID,SemesterID)
Ça va gérer uniquement le prénom Il est également beaucoup plus joli/manageable/robuste que la construction dynamique de la chaîne SQL et l'exécution de celle-ci.
Je suis d'accord, c'est plus lisible, mais le plan sera mis en cache juste pour le premier modèle, donc si les performances sont problématiques, l'exécution de SQL dynamique pourrait être une meilleure solution. – muerte
+ 1 Je ferais de même, mais utilisez la syntaxe (@Paremeter est nulle ou Column = @Paremeter) – cmsjr
Jusqu'à ce que vous commenciez à aller vers la direction des paramètres déterminant les jointures que vous utilisez, cette méthode est encore assez bonne sur les performances, @ muerte Et, en règle générale, les performances sont consomptibles - la maintenabilité/la lisibilité ne l'est pas;) –
Je publiais juste le même concept que Kevin Fairchild, c'est ainsi que nous le traitons généralement.
Vous pouvez faire dynamique SQL dans votre code pour créer l'instruction si nécessaire, mais si c'est le cas, vous devez surveiller l'injection de SQL.
Comme le souligne muerte, le plan sera mis en cache pour le premier ensemble de paramètres. Cela peut entraîner de mauvaises performances lors de son exécution à chaque fois en utilisant d'autres paramètres. Pour résoudre cela, utilisez l'option WITH RECOMPILE de la procédure.
- 1. requête de recherche sql pour plusieurs paramètres optionnels
- 2. plusieurs critères de recherche
- 3. Recherche d'une procédure stockée
- 4. recherche plein texte erreur de procédure stockée
- 5. structure de procédure stockée
- 6. MySql retournant plusieurs lignes de la procédure stockée/fonction
- 7. Appel de la procédure stockée
- 8. Procédure stockée renvoie plusieurs jeux d'enregistrements
- 9. Recherche de procédure stockée à l'aide du framework d'entité
- 10. ASP exécuter la procédure stockée avec Null
- 11. Contrôle de plusieurs sorties de procédure stockée SQL en C#
- 12. La meilleure façon de mettre en œuvre une procédure stockée avec recherche en texte intégral
- 13. question de procédure stockée avec IS_MEMBER
- 14. Erreur de procédure stockée
- 15. Marquage du nom de la procédure stockée
- 16. Syntaxe de procédure stockée
- 17. convertir la procédure de MySQL stockée MSSQL
- 18. Hibernation pour l'accès à la procédure stockée
- 19. Exemple de script pour appeler une procédure stockée avec loadrunner?
- 20. Annulation de la procédure stockée Aysnchronous
- 21. éditeur de procédure stockée mysql
- 22. paramètres de procédure stockée MySQL
- 23. "Impossible de trouver la procédure stockée"
- 24. SQL Server - SELECT de la procédure stockée
- 25. Renvoyer le curseur de la procédure stockée
- 26. Recherche de la modularité dans SQL Server 2005 - Retour de plusieurs jeux d'enregistrements dans une procédure stockée
- 27. procédure stockée Linq avec des résultats dynamiques
- 28. Comment faire une recherche avec plusieurs critères à partir d'une base de données avec SQL?
- 29. Récupérer la valeur de retour de la procédure stockée DB2
- 30. Trier par critères de recherche C# LINQ
Comment ce changement si j'avais les paramètres suivants: 1. Lastname (opérateur LIKE) 2. Cours (pas ETC.) 3. L'article (pas ETC.) Avec tous intacts, ce serait: SELECT * FROM courseEnrollment où Nom de famille comme 'Bob%' et cours = '100' et section = '001' – Caveatrob
Modifiez la partie "client_user = @UserName" pour indiquer la condition réelle que vous souhaitez ajouter à votre requête. –