2013-01-07 42 views
2

可能重复:
Parameterizing an SQL IN clause?SQL SELECT语句 - 在IN子句多个ID

时不时地,我一个系统,允许用户选择多个项目,然后执行上工作对他们采取大规模行动。通常情况下,我使出建立在运行时的SQL,像这样:

string inClause = String.Join(", ", selectedIds); 
string command = "SELECT * FROM Customer WHERE CustomerId IN ({0})"; 
command = String.Format(command, inClause); 

当然,这种风格的代码是因为SQL注入的不安全。我可以通过加入参数占位符和创建参数来解决这个问题。

不过,我想知道是否有另一种方法,我没有考虑。我当然不希望为每个ID执行一次命令。

+0

http://stackoverflow.com/a/337792/284240 –

+0

看一看http://stackoverflow.com/questions/337704/parameterizing-an-sql-in-clause –

+0

如果'selectedIds'是一个数组整数,没有SQL注入的危险。没有办法在一个整数中填充一个''''。 – Andomar

回答

1

有两个很好的方法:

  1. 建立与命令的占位符的字符串(像你说的)
  2. 加入到的TVP

燃烧的ID值到SQL是不好,因为它会阻止计划缓存并打开注入的可能性。

0

您可以构建一个XML字符串,然后将其传递给存储过程。执行它会是什么样子:

EXECUTE getLocationTypes '<IDList><ID>1</ID><ID>3</ID></IDList>' 

存储的过程看起来是这样的:

create proc [dbo].[getLocationTypes](@locationIds XML) 
as 
begin 
set nocount on 

SELECT locationId, typeId 
FROM xrefLocationTypes 
WHERE locationId 
IN (SELECT Item.value('.', 'int') 
FROM @locationIDs.nodes('IDList/ID') AS x(Item)) 
ORDER BY 1, 2 

end 

注意参数的数据类型是XML。这比你所做的要复杂一点,猜测你可以在一个单独的SQL字符串中完成。