Mel*_*sus 47 sql in-clause sql-server-2008
假设我得到以下内容:
DECLARE @ExcludedList VARCHAR(MAX)
SET @ExcludedList = 3 + ', ' + 4 + ' ,' + '22'
SELECT * FROM A WHERE Id NOT IN (@ExcludedList)
Run Code Online (Sandbox Code Playgroud)
错误:将varchar值','转换为数据类型int时转换失败.
我理解为什么错误存在,但我不知道如何解决它...
Ton*_*nyP 39
你需要像动态sp一样执行它
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
Run Code Online (Sandbox Code Playgroud)
小智 34
这是一个示例,我使用表变量列出IN子句中的多个值.显而易见的原因是能够在长程序中仅将值列表更改为一个位置.
为了使它更具动态性并允许用户输入,我建议为输入声明一个varchar变量,然后使用WHILE循环传递变量中的数据并将其插入表变量中.
用真实的东西替换@your_list,Your_table和值.
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 )
Run Code Online (Sandbox Code Playgroud)
选择语句abowe将执行相同的操作:
SELECT *
FROM your_table
WHERE your_column in ('value','value2376' )
Run Code Online (Sandbox Code Playgroud)
小智 20
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)
Run Code Online (Sandbox Code Playgroud)
我知道我正在回复一篇旧帖子,但我想分享一个如何在需要避免使用动态SQL时使用变量表的示例.我不确定它是否是最有效的方式,但是当动态SQL不是一个选项时,这对我来说过去了.
您不能在IN
子句中使用变量-您需要使用动态SQL或使用函数(TSQL或CLR)将值列表转换为表。
动态SQL示例:
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
Run Code Online (Sandbox Code Playgroud)
首先,创建一个快速函数,将分隔的值列表拆分为一个表,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
然后像这样调用函数......
SELECT *
FROM A
LEFT OUTER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value
WHERE f.Id IS NULL
Run Code Online (Sandbox Code Playgroud)
这对我们的项目非常有效......
当然,如果是这样的话,也可以做相反的事情(虽然不是你的问题).
SELECT *
FROM A
INNER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value
Run Code Online (Sandbox Code Playgroud)
在处理具有可选多选参数列表的报表时,这非常方便.如果参数为NULL,则需要选择所有值,但如果它具有一个或多个值,则希望在这些值上过滤报表数据.然后像这样使用SQL:
SELECT *
FROM A
INNER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value OR @ExcludeList IS NULL
Run Code Online (Sandbox Code Playgroud)
这样,如果@ExcludeList是NULL值,则连接中的OR子句将成为关闭对此值进行过滤的开关.非常便利...
归档时间: |
|
查看次数: |
163596 次 |
最近记录: |