2

可能重复:
参数化 SQL IN 子句?

我时不时地在一个允许用户选择多个项目然后对它们执行批量操作的系统上工作。通常,我求助于在运行时构建 SQL,如下所示:

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

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

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

4

2 回答 2

1

有两种很好的方法:

  1. 使用命令占位符构建字符串(如您所说)
  2. 加入 TVP 的价值观

将 ID 刻录到 SQL 中并不好,因为它会阻止计划缓存并打开注入的可能性。

于 2013-01-07T16:10:12.100 回答
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 字符串中完成所有操作。

于 2013-01-08T01:21:48.420 回答