web-dev-qa-db-ja.com

ストアドプロシージャを介して "in"リストを渡す

(たとえば)@IDListを渡して次のように記述できるストアドプロシージャを作成するにはどうすればよいですか。

Select * from Foo Where ID in @IDList

これは可能ですか?

17
klkitchens
4
dotjoe

SQL2005以降では、コードから配列を直接送信できます。

最初にカスタムタイプを作成します

CREATE TYPE Array AS table (Item varchar(MAX))

ストアドプロシージャよりも。

CREATE PROCEDURE sp_TakeArray
    @array AS Array READONLY
AS BEGIN
    Select * from Foo Where ID in (SELECT Item FROM @array)
END

次に、DataTableを配列として渡すコードから呼び出します

DataTable items = new DataTable();
items.Columns.Add( "Item", typeof( string ) );

DataRow row = items.NewRow();
row.SetField<string>( "Item", <item to add> );
items.Rows.Add( row );

SqlCommand command = new SqlCommand( "sp_TakeArray", connection );
command.CommandType = CommandType.StoredProcedure;
SqlParameter param = command.Parameters.Add( "@Array", SqlDbType.Structured );
param.Value = items;
param.TypeName = "dbo.Array";

SqlDataReader reader = command.ExecuteReader();
12
bstoney

個々のIDをテーブルBに書き込み、すべて同じ「キー」を使用します(a GUIDおそらく)。
次に、テーブルAに対するクエリには、

where ID in (select ID from B where key = @TempKey)

(キーを使い終わったら、キーを削除することもできます。または、キーにタイムスタンプを付けて、後でsqlジョブで削除することもできます。)

長所:

  • 文字列を送信しないため、状況によってはSQLインジェクションにさらされる可能性があります。
  • 他のアプリロジックによっては、可能性を一度に追跡したり、書き込んだりする必要はありません。

短所:

  • 特に負荷が大きい場合、非常に非効率になる可能性があります。
0
Doug L.