Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sane/fast method to pass variable parameter lists to SqlServer2008 stored procedure

A fairly comprehensive query of the brain has turned up a thousand and one ways to pass variable length parameter lists that involve such methods as:

  • CLR based methods for parsing strings to lists of integers
  • Table valued functions that require the presence of a 'Numbers' table (wtf?)
  • Passing the data as XML

Our requirements are to pass two variable length lists of integers (~max 20 ints) to a stored procedure. All methods outlined above seem to smell funny.

Is this just the way it has to be done, or is there a better way?

Edit: I've just found this, which may qualify this question as a dupe

like image 371
spender Avatar asked Apr 21 '09 14:04

spender


People also ask

How do you pass a list of values to a parameter of a stored procedure?

CREATE FUNCTION dbo. SplitInts ( @List VARCHAR(MAX), @Delimiter VARCHAR(255) ) RETURNS TABLE AS RETURN ( SELECT Item = CONVERT(INT, Item) FROM ( SELECT Item = x.i.value('(./text())[1]', 'varchar(max)') FROM ( SELECT [XML] = CONVERT(XML, '<i>' + REPLACE(@List, @Delimiter, '</i><i>') + '</i>').

Can you pass a list to a stored procedure?

There are several ways to do this. While using older versions of SQL Server, I've used to the XML method to pass array or list to stored procedure. In the latest versions of SQL Server, we can use the User Defined Data Type (UDT) with a base type of table to send array or list through a parameter.

Can pass 3 types of parameters to stored procedures What are they?

As a program, a stored procedure can take parameters. There are three types of parameters: IN, OUT and INOUT.


2 Answers

Yes, I'd definitely look at Table Valued Parameters for this. As a side benefit, it may allow you to use a nice, clean set-based implementation for the innards of your procedure directly, without any data massaging required.

Here's another reference as well...

like image 92
mwigdahl Avatar answered Oct 13 '22 19:10

mwigdahl


Here is a fairly fast method to split strings using only T-SQL and you input parameter is only a string. You need to have a table and a function (as described below) already set up to use this method.

create this table:

CREATE TABLE Numbers (Number  int not null primary key identity(1,1))
DECLARE @n int
SET @n=1
SET IDENTITY_INSERT Numbers ON
WHILE @N<=8000
BEGIN
    INSERT INTO Numbers (Number) values (@n)
    SET @n=@n+1
END
SET IDENTITY_INSERT Numbers OFF

create this function to split the string array (I have other versions, where empty sections are eliminated and ones that do not return row numbers):

CREATE FUNCTION [dbo].[FN_ListAllToNumberTable]
(
     @SplitOn              char(1)              --REQUIRED, the character to split the @List string on
    ,@List                 varchar(8000)        --REQUIRED, the list to split apart
)
RETURNS
@ParsedList table
(
    RowNumber int             --REQUIRED, the list to split apart
   ,ListValue varchar(500)    --OPTIONAL, the character to split the @List string on, defaults to a comma ","

)
AS
BEGIN

--this will return empty rows, and row numbers
INSERT INTO @ParsedList
        (RowNumber,ListValue)
    SELECT
        ROW_NUMBER() OVER(ORDER BY number) AS RowNumber
            ,LTRIM(RTRIM(SUBSTRING(ListValue, number+1, CHARINDEX(@SplitOn, ListValue, number+1)-number - 1))) AS ListValue
        FROM (
                 SELECT @SplitOn + @List + @SplitOn AS ListValue
             ) AS InnerQuery
            INNER JOIN Numbers n ON n.Number < LEN(InnerQuery.ListValue)
        WHERE SUBSTRING(ListValue, number, 1) = @SplitOn

RETURN

END 
go

here is an example of how to split the parameter apart:

CREATE PROCEDURE TestPass
(
    @ArrayOfInts    varchar(255)  --pipe "|" separated list of IDs
)
AS

SET NOCOUNT ON

DECLARE @TableIDs  TABLE (RowNumber int, IDValue int null)

INSERT INTO @TableIDs (RowNumber, IDValue)  SELECT RowNumber,CASE WHEN LEN(ListValue)<1 then NULL ELSE  ListValue END FROM dbo.FN_ListAllToNumberTable('|',@ArrayOfInts)

SELECT * FROM @TableIDs
go

this is based on: http://www.sommarskog.se/arrays-in-sql.html

like image 26
KM. Avatar answered Oct 13 '22 21:10

KM.