Передача списка "in" с помощью хранимой процедуры

Как я могу построить хранимую процедуру, которая позволит мне передать (например) @IDList, чтобы я мог написать:

Select * from Foo Where ID in @IDList

Это выполнимо?

Ответы

Ответ 2

С 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();

Ответ 3

Напишите отдельные идентификаторы в таблицу B, все с одним и тем же "ключом" (возможно, GUID).
Затем ваш запрос к таблице A будет включать

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

(Вы можете удалить ключи, если вы закончили с ними. Или отметьте их временем и выполните sql-задание позже).

Плюсы:

  • Вы не отправляете строку, которая может привести вас к SQL-инъекции в некоторых случаях.
  • В зависимости от вашей другой логики приложения вам не нужно отслеживать или записывать все возможности сразу.

Минусы:

  • Это может быть крайне неэффективно, особенно при тяжелых нагрузках.