2013-01-07 80 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字符串中完成。