我正在运行SQL Server,我有一个存储过程。我想用WHERE IN子句做一个select语句。我不知道列表会有多长时间,所以我现在尝试了以下内容
SELECT * FROM table1 WHERE id IN (@idList)
在这个解决方案中@idList是一个varChar(max)。但这不起作用。我听说传递表值,但我对如何做到这一点很困惑。任何帮助都会很棒
答案 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)
如果更长,请寻找分割功能。