Mon code SQL est assez simple. J'essaie de sélectionner des données d'une base de données comme celle-ci:
SELECT * FROM DBTable
WHERE id IN (1,2,5,7,10)
Je veux savoir comment déclarer la liste avant la sélection (dans une variable, une liste, un tableau ou quelque chose) et dans la sélection uniquement utiliser le nom de la variable, quelque chose comme ceci:
VAR myList = "(1,2,5,7,10)"
SELECT * FROM DBTable
WHERE id IN myList
Vous pouvez déclarer une variable en tant que table temporaire comme ceci:
declare @myList table (Id int)
Cela signifie que vous pouvez utiliser l'instruction insert
pour la renseigner avec des valeurs:
insert into @myList values (1), (2), (5), (7), (10)
Ensuite, votre instruction select
peut utiliser l’instruction in
:
select * from DBTable
where id in (select Id from @myList)
Ou vous pouvez rejoindre la table temporaire comme ceci:
select *
from DBTable d
join @myList t on t.Id = d.Id
Et si vous faites souvent quelque chose comme cela, vous pouvez envisager de définir un type de table défini par l'utilisateur afin de pouvoir déclarer votre variable comme suit:
declare @myList dbo.MyTableType
Cela n'est pas possible avec une requête normale car la clause in
nécessite des valeurs distinctes et non une valeur unique contenant une liste séparée par des virgules. Une solution serait une requête dynamique
declare @myList varchar(100)
set @myList = '(1,2,5,7,10)'
exec('select * from DBTable where id IN ' + @myList)
Si vous voulez entrer et appliquer une chaîne séparée par des virgules dans la requête, vous pouvez alors créer Function comme:
create FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))
returns @temptable TABLE (items varchar(MAX))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end;
Vous pouvez l'utiliser comme:
Declare @Values VARCHAR(MAX);
set @Values ='1,2,5,7,10';
Select * from DBTable
Where id in (select items from [dbo].[Split] (@Values, ',') )
Sinon, si vous n'avez pas de chaîne séparée par des virgules en entrée, vous pouvez essayer Table variable
OR TableType
ou Temp table
comme: INSERT en utilisant LIST dans la procédure stockée
J'ai toujours trouvé plus facile d'inverser le test par rapport à la liste dans des situations comme celle-ci. Par exemple...
SELECT
field0, field1, field2
FROM
my_table
WHERE
',' + @mysearchlist + ',' LIKE '%,' + CAST(field3 AS VARCHAR) + ',%'
Cela signifie qu'il n'y a pas de méli-mélo compliqué requis pour les valeurs que vous recherchez.
Par exemple, si notre liste était ('1,2,3')
, nous ajoutons une virgule au début et à la fin de notre liste comme suit: ',' + @mysearchlist + ','
.
Nous procédons également de la même manière pour la valeur de champ recherchée et ajoutons des caractères génériques: '%,' + CAST(field3 AS VARCHAR) + ',%'
(notez les caractères %
et ,
).
Enfin, nous testons les deux en utilisant l'opérateur LIKE
: ',' + @mysearchlist + ',' LIKE '%,' + CAST(field3 AS VARCHAR) + ',%'
.
Alternative à Peter Monks.
Si le nombre dans l'instruction 'in' est petit et fixe.
DECLARE @var1 varchar(30), @var2 varchar(30), @var3 varchar(30);
SET @var1 = 'james';
SET @var2 = 'same';
SET @var3 = 'dogcat';
Select * FROM Database Where x in (@var1,@var2,@var3);
Vous pouvez convertir la liste des valeurs transmises en un paramètre de valeur de table, puis sélectionner cette liste.
DECLARE @list NVARCHAR(MAX)
SET @list = '1,2,5,7,10';
DECLARE @pos INT
DECLARE @nextpos INT
DECLARE @valuelen INT
DECLARE @tbl TABLE (number int NOT NULL)
SELECT @pos = 0, @nextpos = 1;
WHILE @nextpos > 0
BEGIN
SELECT @nextpos = charindex(',', @list, @pos + 1)
SELECT @valuelen = CASE WHEN @nextpos > 0
THEN @nextpos
ELSE len(@list) + 1
END - @pos - 1
INSERT @tbl (number)
VALUES (convert(int, substring(@list, @pos + 1, @valuelen)))
SELECT @pos = @nextpos;
END
SELECT * FROM DBTable WHERE id IN (SELECT number FROM @tbl);
Dans cet exemple, la chaîne passée dans '1,2,5,7,10' est divisée par des virgules et chaque valeur est ajoutée en tant que nouvelle ligne dans la variable de table @tbl
. Ceci peut ensuite être sélectionné en utilisant le SQL standard.
Si vous envisagez de réutiliser cette fonctionnalité, vous pouvez aller plus loin et la convertir en une fonction.