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ごとにコマンドを1回実行したくないのは確かです。

4

2 に答える 2

1

2 つの適切なアプローチがあります。

  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 に答える