Sane/fast方法将变量参数列表传递给SqlServer2008存储过程

Sane/fast方法将变量参数列表传递给SqlServer2008存储过程,sql,sql-server,sql-server-2008,stored-procedures,parameters,Sql,Sql Server,Sql Server 2008,Stored Procedures,Parameters,一个相当全面的大脑查询已经找到了一千零一种传递可变长度参数列表的方法,包括以下方法: 用于将字符串解析为整数列表的基于CLR的方法 需要(wtf?)的表值函数 我们的要求是向存储过程传递两个可变长度的整数列表(~最多20个整数)。上面列出的所有方法似乎都很有趣 这只是必须要做的事情,还是有更好的方法 编辑: 我刚刚发现,这可能会使这个问题成为一个重复的问题是的,我肯定会看看这个。作为一个附带的好处,它可以让您直接在过程的内部使用一个漂亮的、干净的、基于集合的实现,而不需要任何数据处理 这里

一个相当全面的大脑查询已经找到了一千零一种传递可变长度参数列表的方法,包括以下方法:

  • 用于将字符串解析为整数列表的基于CLR的方法
  • 需要(wtf?)的表值函数
我们的要求是向存储过程传递两个可变长度的整数列表(~最多20个整数)。上面列出的所有方法似乎都很有趣

这只是必须要做的事情,还是有更好的方法

编辑:
我刚刚发现,这可能会使这个问题成为一个重复的问题是的,我肯定会看看这个。作为一个附带的好处,它可以让您直接在过程的内部使用一个漂亮的、干净的、基于集合的实现,而不需要任何数据处理


这里还有…

这里有一个非常快速的方法,可以仅使用T-SQL拆分字符串,并且您输入的参数仅为字符串。您需要已经设置了一个表和一个函数(如下所述)才能使用此方法

创建此表:

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
创建表编号(编号int非空主键标识(1,1))
声明@n int
设置@n=1
设置标识\u在上插入数字
虽然@N+1-是,TVP是SQL Server中这个古老问题的解决方案!我对“数字”表的最初反应与你的类似。事实证明,对于这项任务和其他类似任务,它是一种被广泛接受的方法。它由(备受推崇的)杰夫·摩登推广。请参阅以下文章进行深入讨论:,以及
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
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