我在SSRS(2008)中创建了一个报告,报告的数据来自MS SQL中的存储过程。
我想要一个多值参数(完成这一百万次,但没有一个SP)
我已经根据查询创建了参数,勾选了允许多个值并修改了SP以使用IN语句(所以IN(@Param))
它只是不工作SQL Server探查器显示这被传递
@RC=N'1,2'
如果我选择一个值,它会起作用(返回一个值)
我看过关于分裂加入的帖子,我尝试了所有这些无济于事。
任何想法(当然它很简单!!)理想情况下,id也能够返回NULL(或者说太多了吗?
谢谢大家
答案 0 :(得分:0)
在您的数据库中创建此功能:
USE [YourDatabase]
GO
/****** Object: UserDefinedFunction [dbo].[SplitListToTable] Script Date: 5/21/2018 8:13:29 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--==========================================================
-- Author: Gugg
-- Created: 2015-10-06
-- Description: Converts a delimited string into a table of values. Based heavily on code from this url:
-- https://social.msdn.microsoft.com/Forums/sqlserver/en-US/0ead7ceb-3fdd-4625-aa82-1d4195f984b1/passing-multivalue-parameter-in-stored-procedure-ssrs
-- Modification History:
--===========================================================
CREATE FUNCTION [dbo].[SplitListToTable]
(
@List NVARCHAR(2000) ,
@SplitOn NVARCHAR(5)
)
RETURNS @RtnValue TABLE
(
Id INT IDENTITY(1, 1) ,
Value NVARCHAR(100)
)
AS
BEGIN
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;
GO
然后你可以解析你的参数:
SELECT *
FROM YourDatabase.dbo.YourTable
WHERE YourColumn IN(SELECT value FROM dbo.SplitListToTable(@YourParameter, ','))
答案 1 :(得分:0)
我感觉到你的痛苦,我们在使用SP的SSRS时遇到了同样的问题。您确实需要拆分传递给存储过程的值。
在您的存储过程中SQL期待;
Alias.Field1 IN (@RC)
编译为
Alias.Field1 IN ('Value1','Value2,'Value3')
然而,SSRS会将参数值作为一个长字符串传递(为什么MS的确超出了我)并最终成为了这个
Alias.Field1 IN ('Value1,Value2,Value3')
正如您正确指出的那样,您无法控制。所以你需要使用Split Strings函数。 Aaron Bertrand在SQLPerformance.com上发表了关于这篇文章的精彩博文,根据数据库的大小为您提供了各种方法的优缺点。我们使用了SplitStrings CTE,因为它为我们大多数数据库的大小提供了最佳性能。
这是功能;
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,',')))