J'ai une requête Transact-SQL qui utilise l'opérateur IN. Quelque chose comme ça:
select * from myTable where myColumn in (1,2,3,4)
Existe-t-il un moyen de définir une variable pour contenir la liste entière "(1,2,3,4)"? Comment devrais-je le définir?
declare @myList {data type}
set @myList = (1,2,3,4)
select * from myTable where myColumn in @myList
Réponses:
la source
la source
[Err] 42000 - [SQL Server]Must declare the scalar variable "@mylist".
(VALUES (1),(2),(3),(4),(5))
directement?Il existe deux façons de traiter les listes csv dynamiques pour les requêtes TSQL:
1) En utilisant une sélection intérieure
2) Utilisation de TSQL concaténé dynamiquement
3) Une troisième option possible est les variables de table. Si vous disposez de SQl Server 2005, vous pouvez utiliser une variable de table. Si vous êtes sur Sql Server 2008, vous pouvez même passer des variables de table entières en tant que paramètre aux procédures stockées et l'utiliser dans une jointure ou comme sous-sélection dans la clause IN.
la source
Utilisez une fonction comme celle-ci:
Au lieu d'utiliser like, vous créez une jointure interne avec la table retournée par la fonction:
devient
Dans une table d'enregistrement 1M non indexée, la deuxième version a pris environ la moitié du temps ...
à votre santé
la source
Veuillez noter que pour les systèmes de longue liste ou de production, il n'est pas recommandé d'utiliser cette méthode car elle peut être beaucoup plus lente qu'un
IN
opérateur simple commesomeColumnName in (1,2,3,4)
(testé avec une liste de 8000+ éléments)la source
Non, ce type n'existe pas. Mais il y a quelques choix:
Aucun de ceux-ci n'est vraiment élégant, mais c'est le meilleur qui soit.
la source
légère amélioration sur @LukeH, il n'est pas nécessaire de répéter le "INSERT INTO": et la réponse de @ realPT - pas besoin d'avoir le SELECT:
la source
Je sais que c'est vieux maintenant mais TSQL => 2016, vous pouvez utiliser STRING_SPLIT:
la source
À partir de SQL2017, vous pouvez utiliser STRING_SPLIT et faire ceci:
la source
Si vous voulez faire cela sans utiliser une deuxième table, vous pouvez faire une comparaison LIKE avec un CAST:
Si le champ que vous comparez est déjà une chaîne, vous n'aurez pas besoin de CAST.
Entourer à la fois la correspondance de colonne et chaque valeur unique entre des virgules garantira une correspondance exacte. Sinon, une valeur de 1 serait trouvée dans une liste contenant ', 4,2,15,'
la source
Comme personne ne l'a mentionné auparavant, à partir de Sql Server 2016, vous pouvez également utiliser des tableaux json et
OPENJSON (Transact-SQL)
:Vous pouvez le tester dans sql fiddle demo
Vous pouvez également couvrir des cas plus complexes avec json plus facilement - voir Rechercher une liste de valeurs et une plage en SQL à l'aide de la clause WHERE IN avec une variable SQL?
la source
Celui-ci utilise PATINDEX pour faire correspondre les identifiants d'une table à une liste d'entiers non délimités par des chiffres.
Remarques:
la source
la source
Je pense que vous devrez déclarer une chaîne, puis exécuter cette chaîne SQL.
Jetez un œil à sp_executeSQL
la source