假设我有以下内容:
DECLARE @ExcludedList VARCHAR(MAX)
SET @ExcludedList = 3 + ', ' + 4 + ' ,' + '22'
SELECT * FROM A WHERE Id NOT IN (@ExcludedList)
错误:将varchar值', '转换为数据类型int时转换失败。
我知道为什么会出现这个错误,但我不知道该如何解决它...
假设我有以下内容:
DECLARE @ExcludedList VARCHAR(MAX)
SET @ExcludedList = 3 + ', ' + 4 + ' ,' + '22'
SELECT * FROM A WHERE Id NOT IN (@ExcludedList)
错误:将varchar值', '转换为数据类型int时转换失败。
我知道为什么会出现这个错误,但我不知道该如何解决它...
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 )
SELECT *
FROM your_table
WHERE your_column in ('value','value2376' )
你需要将此作为动态存储过程执行
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
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)
我知道我在回复一个旧帖子,但我想分享一个使用变量表的例子,当一个人想要避免使用动态SQL时。 我不确定这是否是最有效的方法,但在以前无法使用动态SQL时,这对我有用过。
EXEC(@IDQuery)
是动态的? - David R TribbleDECLARE @SomeTableVar TABLE(id INT)
INSERT INTO @SomeTableVar SELECT some_int FROM some_table
WHERE some_int IS NOT NULL
SELECT * FROM @SomeTableVar
我认为这只是一个人为的例子。顺便说一下,对于任何评论回复垃圾邮件,我很抱歉。
我是个大笨蛋,不明白在StackOverflow上,评论标记与答案标记不同。 :v - Elijah WoodwardIN
语句中使用变量,需要使用动态SQL或使用函数(TSQL或CLR)将值列表转换为表格。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
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
SELECT *
FROM A
LEFT OUTER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value
WHERE f.Id IS NULL
这在我们的项目中表现得非常好...
当然,如果情况相反,也可以做相反的事情(尽管这不是你的问题)。
SELECT *
FROM A
INNER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value
当处理具有可选多选参数列表的报告时,这将非常方便。如果参数为NULL,则选择所有值,但如果它具有一个或多个值,则希望报告数据根据这些值进行过滤。然后使用以下SQL:
SELECT *
FROM A
INNER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value OR @ExcludeList IS NULL
这样,如果@ExcludeList是一个NULL值,在连接中的OR子句就会变成一个开关,关闭对该值的过滤。非常方便...
我认为问题出在
3 + ', ' + 4
将其更改为
'3' + ', ' + '4'
DECLARE @ExcludedList VARCHAR(MAX)
SET @ExcludedList = '3' + ', ' + '4' + ' ,' + '22'
SELECT * FROM A WHERE Id NOT IN (@ExcludedList)
设置@ExcludedList,使您的查询变为
要么
SELECT * FROM A WHERE Id NOT IN ('3', '4', '22')
或者
SELECT * FROM A WHERE Id NOT IN (3, 4, 22)
试试这个:
CREATE PROCEDURE MyProc @excludedlist integer_list_tbltype READONLY AS
SELECT * FROM A WHERE ID NOT IN (@excludedlist)
然后像这样调用它:
DECLARE @ExcludedList integer_list_tbltype
INSERT @ExcludedList(n) VALUES(3, 4, 22)
exec MyProc @ExcludedList
我有另一种解决方案,可以不使用动态查询来完成。 我们也可以借助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)
这里是完整的解决方案: http://raresql.com/2011/12/21/how-to-use-multiple-values-for-in-clause-using-same-parameter-sql-server/
string_split
函数,将你的代码更改为select * from A where Id not In (select value from string_split('3;4;5;6',';'))
。 - Guokas