我正在处理报告服务中的报告,该报告让用户从多值列表中选择多个项目。报告的查询使用简单的结果列表
SELECT foo FROM bar WHERE foobar IN(@SelectedItemsFromMultiValueList)
我现在正在改变报告,需要使用游标迭代@SelectedItemsFromMultiValueList中的项目。我环顾四周但无法弄清楚如何做到这一点 - 由于我不确定在IN中使用的值列表甚至是手动声明一个(例如DECLARE @)这一事实使得更加困难SelectedItemsFromMultiValueList ???)
是否有人知道如何在多值列表参数上进行游标或如何在SQL中调用类似的内容以便我可以更有效地搜索解决方案?
答案 0 :(得分:1)
您的多值列表将作为逗号分隔值列表(即“31,26,17”)
进入sql要迭代这些值,您需要一种将值拆分为表格的方法。这是我用过的一个函数,我相信最初是由Jens Suessmeyer编写的:
CREATE FUNCTION [dbo].[ufn_split]
( @Delimiter varchar(5),
@List nvarchar(max)
)
RETURNS @TableOfValues table
( RowID smallint IDENTITY(1,1),
[Value] NVARCHAR(max)
)
AS
BEGIN
DECLARE @LenString int
WHILE len( @List ) > 0
BEGIN
SELECT @LenString =
(CASE charindex( @Delimiter, @List )
WHEN 0 THEN len( @List )
ELSE ( charindex( @Delimiter, @List ) -1 )
END
)
INSERT INTO @TableOfValues
SELECT substring( @List, 1, @LenString )
SELECT @List =
(CASE ( len( @List ) - @LenString )
WHEN 0 THEN ''
ELSE right( @List, len( @List ) - @LenString - 1 )
END
)
END
RETURN
END
所以你调用这个函数,传递它@SelectedItemsFromMultiValueList,然后它会返回一个值表,你可以用你想要的那样做。
例如:
SELECT * FROM Foo WHERE X IN (SELECT [value] FROM dbo.ufn_split(',', @SelectedItemsFromMultiValueList)
答案 1 :(得分:1)
我更喜欢使用递归cte
的基于集合的解决方案declare @delim varchar(max),
@string varchar(max)
set @delim=','
set @string='1,2,3,4,5,6,7,8,9,10'
;with c as
(
select
CHARINDEX(@delim,@string,1) as Pos,
case when CHARINDEX(@delim,@string,1)>0 then SUBSTRING(@string,1,CHARINDEX(@delim,@string,1)-1) else @string end as Value,
case when CHARINDEX(@delim,@string,1)>0 then SUBSTRING(@string,CHARINDEX(@delim,@string,1)+1,LEN(@string)-CHARINDEX(@delim,@string,1)) else '' end as String
union all
select
CHARINDEX(@delim,String,1) as Pos,
case when CHARINDEX(@delim,String,1)>0 then SUBSTRING(String,1,CHARINDEX(@delim,String,1)-1) else String end as Value,
case when CHARINDEX(@delim,String,1)>0 then SUBSTRING(String,CHARINDEX(@delim,String,1)+1,LEN(String)-CHARINDEX(@delim,String,1)) else '' end as String
from c
where LEN(String)>0
)
select
Value
from c
option (maxrecursion 10000)
然后你接受任何查询,并使用c进行内连接。