2

Context: I have an SSRS report with a multi-value parameter. The report passes the multi-value parameter to a stored procedure that assigns it to a variable of an nvarchar type. This variable contains unique IDs that map to values in the DB that are actually stored as an int data type.

Details: Basically I need to a) Modify the ssrs report to allow for multi-value entry (which i've already done) b) split_string the nvarchar variable into consumable int type pieces c) process the query with these pieces d) re-construct the string to present the query results in a concatenated fashion per user requirements

Questions: Can you please assist in finding the most efficient way to perform these transformations in the proc I've (attempted) to draft below?

Side note: While I've found some posts related to handling multi-value ssrs parameters in procs here, here and here -- they aren't fixes that apply to my specific scenario given the multiple rounds of transformation needed.

/*This is the parameter supplied by the SSRS report that needs to be split, just declared here for commentary purposes
DECLARE @p_catalog_id nvarchar(max);
SET @p_catalog_id = '163650,163651,163652,163653,163654,163655,163656,163657,310415';
*/

BEGIN 

WITH EPV_IDs
AS
    (
        SELECT h.CATALOG_ID,
               h.PARENT_Catalog_ID as 'Series Collection ID',
               c.catalog_template as Template,
               d.CATALOG_ID as 'EPV ID'
        FROM [RDW_DIV38].[dbo].[Catalog_LINK_Catalog] as h 
          inner join [RDW_DIV38].[dbo].[Catalog] as c on c.Catalog_ID = h.CATALOG_ID
          left join [RDW_DIV38].[dbo].[Catalog_LINK_Catalog] as d on d.PARENT_Catalog_ID = h.PARENT_Catalog_ID
          inner join [RDW_DIV38].[dbo].[Catalog] as f on f.catalog_id=H.PARENT_Catalog_ID
        WHERE c.catalog_template = 'Episode Version'
          and f.catalog_template='series Collection'
          and c.Catalog_STATUS not in ('Withdrawn', 'Cancelled')
          and f.Catalog_STATUS not in ('Withdrawn', 'Cancelled')
          and d.Catalog_ID = @p_catalog_id
    ), 
X
AS
    (
        SELECT  EPV_IDs.[Series Collection ID],
                EPV_IDs.[Template],
                EPV_IDs.[EPV ID],
                COUNT(EPV_IDs.[EPV ID])as 'All EPVs'
        FROM EPV_IDs
        GROUP BY EPV_IDs.[Series Collection ID], EPV_IDs.[Template], EPV_IDs.[EPV ID]
    ),
y
AS
    (
        SELECT X.[Series Collection ID], 
               X.[Template],
               case when COUNT(X.[EPV ID]) = X.[All EPVs] Then 'Yes' Else 'No' ENd as 'Full?',
               COUNT(X.[EPV ID]) as 'EPVs Found',
               X.[All EPVs],STRING_AGG(X.[EPV ID],',')as 'EPV IDs'
        FROM X
        GROUP BY X.[Series Collection ID] ,X.[Template],x.[All EPVs]
    ), 
A
AS
    (
        SELECT x.[EPV ID],
               y.[Series Collection ID],
               y.[Template],
               STRING_AGG(y.[Full?],'/')as [Full?],
               y.[EPVs Found],
               y.[All EPVs],
               y.[EPV IDs]
        FROM y
        inner join x on x.[Series Collection ID]=y.[Series Collection ID]
        GROUP BY x.[EPV ID], y.[Series Collection ID], y.[Template], y.[EPVs Found], y.[All EPVs], y.[EPV IDs]
    )
        SELECT DISTINCT a3.[Series Collection ID] as Series_Collection_ID,
                        a3.[Template],
                        a.[Full?] as [Full],
                        a3.[EPVs Found] as EPVs_Found,
                        a3.[All EPVs] as All_EPVs,
                        a3.[EPV IDs] as EPV_IDs
        FROM a
        left join a as a3 on  a3.[EPV ID]=a.[EPV ID]
        WHERE not exists (

                           SELECT 1
                           FROM a a2
                           WHERE a2.[EPV ID] =a.[EPV ID] and  a2.[Full?] = 'Yes'

                         )
        UNION
        SELECT a.[Series Collection ID] as Series_Collection_ID,
               a.[Template],
               a.[Full?] as [Full],
               a.[EPVs Found] as EPVs_Found,
               a.[All EPVs] as All_EPVs,
               a.[EPV IDs] as EPV_IDs
        FROM a
        WHERE a.[Full?]='Yes'

END
1
  • thanks @fandango68 but I'm not passing text from a webpage in an asp.net application. and also i'm passing multiple parameters each with its own value into the stored procedure. your blog mentions this not being covered as a solution. Commented Mar 13, 2019 at 16:54

1 Answer 1

2

if your database is 2016 then you can just use string_split: Replace

and d.Catalog_ID = @p_catalog_id

with

and CAST(d.Catalog_ID as varchar(10)) IN (SELECT value FROM STRING_SPLIT(@p_catalog_id, ',')

Otherwise i'd suggest you use the FOR XML PATH approach - lots of egs out there & others too: https://sqlperformance.com/2012/07/t-sql-queries/split-strings

Sign up to request clarification or add additional context in comments.

1 Comment

Since I cant trust the freetext the user inputs i'm not surs FOR XML PATH is the best option. I'll try your other suggestion though, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.