2
votes

I have a report im creating in SSRS (2008) and the data for the report is coming from a stored procedure in MS SQL.

I want to have a multiple value parameter (done this a million time but not with a SP)

I have created the parameter based on a query, ticked the allow multiple values and modified the SP to use the IN statement (so IN (@Param))

It just wont work SQL Server profiler show this being passed

@RC=N'1,2'

If I choose one value, it works (returning the one value)

I have seen posts about splitting joining and i've tried all these to no avail.

Any ideas (surely its simple!!) Ideally id like to be able to return NULL too (or is that too much to ask?

Thank you all

2
Just trying to understand a bit more here, you are trying to pass multiple comma separated values as one of your parameter to your stored procedure which is not working?Abhishek
@abhishek SSRS passes the parameters in a pre defined format that I seem to have no control over (other than change the data type) @RC=N'1,2,3,4,5,6,7,8,9' could be sent if i select a few (I would prefer @RC='1','2','3','4' but it seems that cant be done.Leighbee
Check out Table Valued Parameters.Jacob H

2 Answers

1
votes

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, ','))
1
votes

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,',')))