我感觉到你的痛苦,我们在使用带有 SP 的 SSRS 时遇到了同样的问题。您确实需要拆分要传递给存储过程的值。
在您的存储过程中期待 SQL;
Alias.Field1 IN (@RC)
编译成
Alias.Field1 IN ('Value1','Value2,'Value3')
但是,SSRS 会将参数值作为一个长字符串传递(MS 为什么这样做超出了我的理解),最终会变成这样
Alias.Field1 IN ('Value1,Value2,Value3')
正如您正确指出的那样,您对此的控制权为零。因此,您需要使用拆分字符串功能。 Aaron Bertrand 在SQLPerformance.com 上写了一篇很棒的博文,根据数据库的大小为您提供了每种方法的优缺点。我们使用了 SplitStrings CTE,因为它在我们大多数 DB 的大小下提供了最佳性能。
这里是函数;
CREATE FUNCTION [dbo].[fn_SplitStringsCTE]
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS @Items TABLE (Item NVARCHAR(4000))
WITH SCHEMABINDING
AS
BEGIN
DECLARE @ll INT = LEN(@List) + 1, @ld INT = LEN(@Delimiter);
WITH a AS
(
SELECT
[start] = 1,
[end] = COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, 1), 0), @ll),
[value] = SUBSTRING(@List, 1,
COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, 1), 0), @ll) - 1)
UNION ALL
SELECT
[start] = CONVERT(INT, [end]) + @ld,
[end] = COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, [end] + @ld), 0), @ll),
[value] = SUBSTRING(@List, [end] + @ld,
COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, [end] + @ld), 0), @ll)-[end]-@ld)
FROM a
WHERE [end] < @ll
)
INSERT @Items SELECT [value]
FROM a
WHERE LEN([value]) > 0
OPTION (MAXRECURSION 0);
RETURN;
END
GO
这是在存储过程中实现它的方法;
AND (Alias.Field1 IN (SELECT Item FROM [dbo].[fn_SplitStringsCTE](@RC,',')))
至于将 NULL 传递给存储过程,这也是我们想要做的事情,但决定使用以下内容,然后向您的 SSRS 参数添加一个传递“所有值”的值,这是一个很好的捕获 -当我们想要返回该参数的所有值时,这一切都是为了我们,但是如果您的数据集中有 NULL,它们也需要被处理。
AND (@RC = 'All Values' OR Alias.Field1 IN (SELECT Item FROM [dbo].[fn_SplitStringsCTE](@RC,',')))