Disons que j'ai ce qui suit:
DECLARE @ExcludedList VARCHAR(MAX)
SET @ExcludedList = 3 + ', ' + 4 + ' ,' + '22'
SELECT * FROM A WHERE Id NOT IN (@ExcludedList)
Erreur: la conversion a échoué lors de la conversion de la valeur varchar ',' en type de données int.
Je comprends pourquoi l'erreur est là mais je ne sais pas comment le résoudre ...
Vous devez exécuter ceci comme un sp dynamique comme
DECLARE @ExcludedList VARCHAR(MAX)
SET @ExcludedList = '3,4,22,6014'
declare @sql nvarchar(Max)
Set @sql='SELECT * FROM [A] WHERE Id NOT IN ('+@ExcludedList+')'
exec sp_executesql @sql
Ceci est un exemple où j'utilise la variable de table pour répertorier plusieurs valeurs dans une clause IN. La raison évidente est de ne pouvoir modifier la liste de valeurs qu’un seul endroit dans une procédure longue.
Pour rendre la saisie encore plus dynamique et plus lisible, je suggère de déclarer une variable varchar pour l’entrée, puis d’utiliser un WHILE pour effectuer une boucle dans les données de la variable et les insérer dans la variable de table.
Remplacez @your_list, Your_table et les valeurs par des éléments réels.
DECLARE @your_list TABLE (list varchar(25))
INSERT into @your_list
VALUES ('value1'),('value2376')
SELECT *
FROM your_table
WHERE your_column in ( select list from @your_list )
La déclaration select ci-dessous fera la même chose que:
SELECT *
FROM your_table
WHERE your_column in ('value','value2376' )
DECLARE @IDQuery VARCHAR(MAX)
SET @IDQuery = 'SELECT ID FROM SomeTable WHERE Condition=Something'
DECLARE @ExcludedList TABLE(ID VARCHAR(MAX))
INSERT INTO @ExcludedList EXEC(@IDQuery)
SELECT * FROM A WHERE Id NOT IN (@ExcludedList)
Je sais que je réponds à un ancien message, mais je voulais partager un exemple d'utilisation des tables de variables lorsque l'on veut éviter d'utiliser du SQL dynamique. Je ne suis pas sûr que ce soit le moyen le plus efficace, mais cela a déjà fonctionné pour moi lorsque le SQL dynamique n'était pas une option.
Vous ne pouvez pas utiliser une variable dans une clause IN
- vous devez utiliser SQL dynamique , ou utiliser ne fonction (TSQL ou CLR) pour convertir la liste de valeurs dans une table .
Exemple de SQL dynamique:
DECLARE @ExcludedList VARCHAR(MAX)
SET @ExcludedList = 3 + ',' + 4 + ',' + '22'
DECLARE @SQL NVARCHAR(4000)
SET @SQL = 'SELECT * FROM A WHERE Id NOT IN (@ExcludedList) '
BEGIN
EXEC sp_executesql @SQL '@ExcludedList VARCHAR(MAX)' @ExcludedList
END
Tout d’abord, créez une fonction rapide qui divisera une liste de valeurs délimitée dans un tableau, comme ceci:
CREATE FUNCTION dbo.udf_SplitVariable
(
@List varchar(8000),
@SplitOn varchar(5) = ','
)
RETURNS @RtnValue TABLE
(
Id INT IDENTITY(1,1),
Value VARCHAR(8000)
)
AS
BEGIN
--Account for ticks
SET @List = (REPLACE(@List, '''', ''))
--Account for 'emptynull'
IF LTRIM(RTRIM(@List)) = 'emptynull'
BEGIN
SET @List = ''
END
--Loop through all of the items in the string and add records for each item
WHILE (CHARINDEX(@SplitOn,@List)>0)
BEGIN
INSERT INTO @RtnValue (value)
SELECT Value = LTRIM(RTRIM(SUBSTRING(@List, 1, CHARINDEX(@SplitOn, @List)-1)))
SET @List = SUBSTRING(@List, CHARINDEX(@SplitOn,@List) + LEN(@SplitOn), LEN(@List))
END
INSERT INTO @RtnValue (Value)
SELECT Value = LTRIM(RTRIM(@List))
RETURN
END
Appelez ensuite la fonction comme ceci ...
SELECT *
FROM A
LEFT OUTER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value
WHERE f.Id IS NULL
Cela a très bien fonctionné sur notre projet ...
Bien entendu, le contraire pourrait également être fait, le cas échéant (bien que ce ne soit pas votre question).
SELECT *
FROM A
INNER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value
Et cela est très utile lorsque vous traitez avec des rapports ayant une liste de paramètres à sélection multiple facultative. Si le paramètre est NULL, vous souhaitez que toutes les valeurs soient sélectionnées, mais s'il contient une ou plusieurs valeurs, vous souhaitez que les données du rapport soient filtrées sur ces valeurs. Ensuite, utilisez SQL comme ceci:
SELECT *
FROM A
INNER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value OR @ExcludeList IS NULL
Ainsi, si @ExcludeList est une valeur NULL, la clause OR dans la jointure devient un commutateur qui désactive le filtrage sur cette valeur. Très pratique ...
Je pense que le problème est dans
3 + ', ' + 4
changez le en
'3' + ', ' + '4'
DECLARE @ExcludedList VARCHAR(MAX)
SET @ExcludedList = '3' + ', ' + '4' + ' ,' + '22'
SELECT * FROM A WHERE Id NOT IN (@ExcludedList)
SET @ExcludedListe pour que votre requête devienne
soit
SELECT * FROM A WHERE Id NOT IN ('3', '4', '22')
o
SELECT * FROM A WHERE Id NOT IN (3, 4, 22)
J'ai une autre solution pour le faire sans requête dynamique. Nous pouvons également le faire avec l’aide de xquery.
SET @Xml = cast(('<A>'+replace('3,4,22,6014',',' ,'</A><A>')+'</A>') AS XML)
Select @Xml
SELECT A.value('.', 'varchar(max)') as [Column] FROM @Xml.nodes('A') AS FN(A)
Voici la solution complète: http://raresql.com/2011/12/21/how-to-use-multiple-values-for-in-clause-using-same-parameter -sql-server/
Essaye ça:
CREATE PROCEDURE MyProc @excludedlist integer_list_tbltype READONLY AS
SELECT * FROM A WHERE ID NOT IN (@excludedlist)
Et puis appelez ça comme ça:
DECLARE @ExcludedList integer_list_tbltype
INSERT @ExcludedList(n) VALUES(3, 4, 22)
exec MyProc @ExcludedList