我不时地在一个允许用户选择多个项目然后对它们执行批量操作的系统上工作。通常,我使用在运行时构建SQL,如下所示:
string inClause = String.Join(", ", selectedIds);
string command = "SELECT * FROM Customer WHERE CustomerId IN ({0})";
command = String.Format(command, inClause);
当然,由于SQL注入,这种代码风格是不安全的。我可以通过放置参数占位符和创建参数来解决这个问题。
不过,我想知道是否有其他方法我没有考虑过。我当然不想为每个ID执行一次命令。
答案 0 :(得分:1)
有两种好方法:
将ID刻录到SQL中并不好,因为它会阻止计划缓存并打开注入的可能性。
答案 1 :(得分: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字符串中完成所有这些。