sqlsql-servert-sqlstored-proceduresin-clause

Is it better to use Custom TABLE TYPE as parameter instead of SQL "IN" clause when passing a large comma separated value


I have a stored procedure it takes comma separated string as input. Which might be too large some times approximately more than 8 thousand characters or more. In that situation, query performance goes down sometimes. And I think there is a limitation for the character length inside the IN clause. For that, sometimes I get errors. Now, I need to know is it better to use a Custom TABLE TYPE as parameter and use Inner JOIN to find the result. If it is then why is it. Here are my 2 stored procedures (minimal code):

CREATE TYPE [dbo].[INTList] AS TABLE(
    [ID] [int] NULL
)

Procedure 1

CREATE PROCEDURE [report].[GetSKU]   
  @list [INTList] READONLY,         
AS 

Select sk.SKUID,sk.Code SCode,sk.SName
FROM SKUs sk
INNER JOIN @list sst ON sst.ID=sk.SKUID

Procedure 2

CREATE PROCEDURE [report].[GetSKU]   
  @params varchar(max),         
AS 
Select sk.SKUID,sk.Code SCode,sk.SName
FROM SKUs sk
WHere CHARINDEX(','+cast( sk.SKUID as varchar(MAX))+',', @params) > 0

Now, which procedures is better to use.

Note: Original Stored Procedures does have few more Joins.


Solution

  • As this question did raise quite some discussion in comments but did not get any viable answer, I'd like to add the major points in order to help future research.

    This question is about: How do I pass a (large) list of values into a query?

    In most cases, people need this either in a WHERE SomeColumn IN(SomeValueList)-filter or to JOIN against this with something like FROM MyTable INNER JOIN SomeValueList ON....

    Very important is the SQL-Server's version, as with v2016 we got two great tools: native STRING_SPLIT() (not position-safe!) and JSON support.

    Furthermore, and rather obvious, we have to think about the scales and values.

    There are several options:

    Table valued paramter (TVP - the best choice)

    A table valued parameter (TVP) must be created in advance (this might be a draw back) but will behave as any other table once created. You can add indexes, you can use it in various use cases and you do not have to bother about anything under the hood.
    Sometimes we cannot use this due to missing rights to use CREATE TYPE...

    Character separated values (CSV)

    With CSV we see three approaches

    Text based containers

    We can pass the list as string, but within a defined format:

    The biggest advantage here: Any programming language provides support for these formats.
    Common obstacles like date and number formatting is solved implicitly. Passing JSON or XML is - in most cases - just some few lines of code.
    Both approaches allow for type- and position-safe queries.
    We can solve our needs without the need to rely on anything existing in advance.