从逗号连续列表创建SQL表

我正在运行SQL Server,我有一个存储过程。 我想用WHERE IN子句做一个select语句。 我不知道列表会有多长时间,所以我现在尝试了以下内容

SELECT * FROM table1 WHERE id IN (@idList) 

在这个解决方案中,@ idList是一个varChar(max)。 但这不起作用。 我听说传递表值,但我对如何做到这一点很困惑。 任何帮助都会很棒

我建议使用一个函数来分割传入列表(使用Martin在评论中添加的链接 )。

将split函数的结果存储在临时表或表变量中,并将其连接到查询而不是WHERE子句中

 select * into #ids from dbo.Split(',', @idList) select t.* from table1 t join #ids i on t.id = is 

最有效的方法是传入一个表值参数(如果你在SQL Server 2008上)或一个XML参数(如果你在SQL Server 2005/2000上)。 如果您的列表很小(并且您在SQL Server 2005/2000上),将列表作为逗号(或其他)分隔列表传递并使用拆分函数将值除以临时表中的行也是一个选项。

无论您使用哪个选项,都可以将此表(表参数,XML选择生成的表或拆分中的值创建的临时表)连接到主查询。

这是一个表值函数,它接受一个nvarchar并返回一个表来连接:

 Create function [ReturnValues] ( @Values nvarchar(4000) ) Returns @ValueTable table(Value nvarchar(2000)) As Begin Declare @Start int Declare @End int Set @Start = 1 Set @End = 1 While @Start <= len(@Values) Begin Set @End = charindex(',', @Values, @Start) If @End = 0 Set @End = len(@Values) + 1 Insert into @ValueTable Select rtrim(ltrim(substring(@Values, @Start, @End - @Start))) Set @Start = @End + 1 End Return End GO 

使用SQL无法按照建议绑定@idList参数。

最好的方法是将ID批量插入到单独的表中,然后使用子选择或加入ID来查询该表。

例如

 INSERT INTO idTable (id, context) values (@idValue, 1); INSERT INTO idTable (id, context) values (@idValue, 1); INSERT INTO idTable (id, context) values (@idValue, 1); // as often as you like SELECT * FROM table1, idTable WHERE table1.id == idTable.id and idTable.context = 1 

上下文必须是标识Id范围的唯一值。 这对于运行存储过程并行非常重要。 如果没有上下文信息,并行运行存储过程将混合来自不同选择的值。

如果参数数量相当小(<100),则可以使用多个参数

 SELECT * FROM table1 WHERE IN id IN (@id1, @id2, @id3) 

如果它更长,请寻找分割function。