ssrs multivalue parameter stored procedure

落花浮王杯 提交于 2019-12-02 05:26:43

Create this function in your database:

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

Then you can parse your parameter like this:

SELECT *
FROM YourDatabase.dbo.YourTable
WHERE YourColumn IN(SELECT value FROM dbo.SplitListToTable(@YourParameter, ','))

I feel your pain, we had the same issue when using SSRS with SP's. You do indeed need to split out the values you are passing to the stored procedure.

In your stored Procedure SQL is expecting;

 Alias.Field1 IN (@RC) 

Which compiles down to

Alias.Field1 IN ('Value1','Value2,'Value3')

However, SSRS will pass the parameter values as one long string (why MS did is beyond me) and will end up being this

Alias.Field1 IN ('Value1,Value2,Value3')

Which, as you correctly pointed out, you have zero control over. So you need to use a Split Strings function. Aaron Bertrand did a great blog post on this one over at SQLPerformance.com which gives you the pros and cons of each method based on the size of your database. We used the SplitStrings CTE as it gave the best performance for the size of most of our DBs.

Here is the function;

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 here is how you implement it in your Stored Procedure;

AND (Alias.Field1 IN (SELECT Item FROM [dbo].[fn_SplitStringsCTE](@RC,',')))

As for passing NULLs to the Stored Procedure, this is also something we wanted to do but instead decided to use the following, and then adding a value to you SSRS parameter that passes 'All Values', it was a nice catch-all for us when we wanted to return all the values of that parameter, but if you have NULLs in your dataset they will also need to be handled.

AND (@RC = 'All Values' OR Alias.Field1 IN (SELECT Item FROM [dbo].[fn_SplitStringsCTE](@RC,',')))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!