Подтвердить что ты не робот

Можно ли отправить набор идентификаторов в качестве параметра ADO.NET SQL?

Eg. могу ли я написать что-то вроде этого кода:

public void InactiveCustomers(IEnumerable<Guid> customerIDs)
{
    //...
    myAdoCommand.CommandText =
        "UPDATE Customer SET Active = 0 WHERE CustomerID in (@CustomerIDs)";
    myAdoCommand.Parameters["@CustomerIDs"].Value = customerIDs;
    //...
}

Единственный способ, которым я знаю, - присоединиться к моему IEnumerable, а затем использовать конкатенацию строк для сборки моей строки SQL.

4b9b3361

Ответ 1

Как правило, путь, которым вы это выполняете, - это передать список значений, разделенных запятыми, и в вашей хранимой процедуре проанализировать список и вставить его в таблицу temp, которую вы затем можете использовать для соединений. Начиная с Sql Server 2005, это стандартная практика для работы с параметрами, требующими хранения массивов.

Вот хорошая статья о различных способах решения этой проблемы:

Передача списка/массива в хранимую процедуру SQL Server

Но для Sql Server 2008 мы, наконец, получаем, чтобы передавать переменные таблицы в процедуры, сначала определяя таблицу как настраиваемый тип.

В этой статье есть хорошее описание этого (и больше возможностей 2008):

Введение в новые возможности программирования T-SQL в SQL Server 2008

Ответ 2

Вы можете с SQL 2008. Он не очень длинный, но он доступен.

Ответ 3

Как уже упоминалось в комментарии, Эрланд Соммарског написал серию статей по этой теме (связанных ниже). Статьи очень тщательны и могут служить справочным материалом. Хотя они специфичны для SQL Server (T-SQL), некоторые из упомянутых технологий могут также работать и для других СУБД (например, с использованием типа данных XML):

Ответ 5

Неа. Параметры похожи на значения SQL в соответствии с первой нормальной формой, в принципе, может быть только один...

Как вы, вероятно, знаете, генерация строк SQL является рискованным бизнесом: вы оставляете себя открытым для SQL injection attack. До тех пор, пока вы имеете дело с добросовестным GUID, вы должны быть в порядке, но в противном случае вы должны обязательно очистить свой ввод.

Ответ 6

Вы не можете передать список как один параметр SQl. Вы можете использовать string.Join(',') GUIDS, такие как "0000-0000-0000-0000, 1111-1111-1111-1111", но это было бы очень дорого накладными и субоптимальными для базы данных. И вы должны передать всю строку в виде одного конкатенированного динамического оператора, вы не можете добавить его в качестве параметра.

Вопрос:

Где вы получаете свой список идентификаторов, которые представляют неактивные клиенты?

Мое предложение - подойти к проблеме немного по-другому. Переместите всю эту логику в базу данных, например:

    Create procedure usp_DeactivateCustomers 
    @inactive varchar(50) /*or whatever values are required to identify inactive customers*/
    AS    
    UPDATE Customer SET c.Active = 0 
    FROM Customer c JOIN tableB b ON c.CustomerID = b.CustomerID 
    WHERE b.someField = @inactive

И назовите его как хранимую процедуру:

public void InactiveCustomers(string inactive)
{
    //...
    myAdoCommand.CommandText =
        "usp_DeactivateCustomers";
    myAdoCommand.Parameters["@inactive"].Value = inactive;
    //...
}

Если в базе данных существует список GUID, зачем мне это нужно: найти их; поместите их в общий список; раскрутите список в переменную CSV/XML/Table, чтобы снова представить их обратно в БД????? Они уже там! Я что-то пропустил?