从逗号连续列表创建SQL表

时间:2010-08-18 19:47:06

标签: c# sql sql-server

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

SELECT * FROM table1 WHERE id IN (@idList)

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

5 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

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

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

select * into #ids from dbo.Split(',', @idList)

select t.*
from table1 t
 join #ids i
    on t.id = i.s

答案 2 :(得分:1)

这是一个表值函数,它接受一个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

答案 3 :(得分:0)

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

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

e.g。

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范围的唯一值。这对于运行存储过程并行非常重要。如果没有上下文信息,并行运行存储过程将混合来自不同选择的值。

答案 4 :(得分:-1)

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

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

如果更长,请寻找分割功能。