Как я могу предоставить List <int> для параметра SQL? - программирование
Подтвердить что ты не робот

Как я могу предоставить List <int> для параметра SQL?

У меня есть оператор SQL, например:

...
const string sql = @"UPDATE PLATYPUS
SET DUCKBILLID = :NEWDUCKBILLID
WHERE PLATYPUSID IN (:ListOfInts)";
...
ocmd.Parameters.Add("ListOfInts", ??WhatNow??);

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

  • Под "разумным" в этом случае я имею в виду между одной и двумя дюжинами.
4b9b3361

Ответ 1

ОБНОВЛЕНИЕ. Как указывает Лассе, вы не можете достичь того, что пытается сделать Клей, используя приведенный ниже метод. Хотя это действительно проходит в списке номеров, разделенных комой, он не будет выполняться, как ожидалось. К сожалению, я не могу удалить это, так как это принятый ответ.


Попробуйте что-то вроде этого:

ocmd.Parameters.Add("ListOfInts", String.Join(",",myList.ToArray());

Метод String.Join принимает все элементы в массиве и помещает указанный символ между ними.

Ответ 2

Вы не можете, вам нужно создать вспомогательную функцию, которая заменяет :ListOfInts на (например) :I0,:I1,:I2... и передает параметр, добавив один за другим в код. Функция, которую вы хотите, изящно эмулируется Dapper.Net в ее поддержка списка.

Ответ 3

Вы не указываете, какую базу данных вы используете, но если это SQL Server 2008+, вы также можете рассмотреть "Табличные параметры" .

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

Ответ 4

Я думаю, что единственным возможным решением является передача значений, разделенных запятыми, которые вы можете преобразовать в таблицу в SQL с помощью функции. Вот функция, которую я использую

CREATE FUNCTION dbo.CSVToList (@CSV varchar(3000)) 
    RETURNS @Result TABLE (Value varchar(30))
AS   
BEGIN
    DECLARE @List TABLE
    (
        Value varchar(30)
    )

    DECLARE
        @Value varchar(30),
        @Pos int

    SET @CSV = LTRIM(RTRIM(@CSV))+ ','
    SET @Pos = CHARINDEX(',', @CSV, 1)

    IF REPLACE(@CSV, ',', '') <> ''
    BEGIN
        WHILE @Pos > 0
        BEGIN
            SET @Value = LTRIM(RTRIM(LEFT(@CSV, @Pos - 1)))

            IF @Value <> ''
                INSERT INTO @List (Value) VALUES (@Value) 

            SET @CSV = RIGHT(@CSV, LEN(@CSV) - @Pos)
            SET @Pos = CHARINDEX(',', @CSV, 1)
        END
    END     

    INSERT @Result
    SELECT
        Value
    FROM
        @List

    RETURN
END

и вы можете использовать следующий код (например) для выполнения операций:

DECLARE @CSV varchar(100)
SET @CSV = '30,32,34,36,40'

SELECT 
    ProductID, 
    ProductName, 
    UnitPrice
FROM 
    Products
WHERE
    ProductID IN (SELECT * FROM dbo.CSVToLIst(@CSV))

Я взял код здесь: http://www.geekzilla.co.uk/view5C09B52C-4600-4B66-9DD7-DCE840D64CBD.htm

Надеюсь, что это поможет.

Ответ 5

Используйте метод Join string в массиве Ints. Вы можете упомянуть comma как разделитель

List<int> ints = new List<int>();
ints.Add(4);
ints.Add(6);
ints.Add(2);

string concatenatedIds= string.Join(",", ints.ToArray());

Выход (значение в concatenatedIds) будет 4,6,2. Вы можете использовать эту строку в качестве значения параметра для вашего предложения IN

ocmd.Parameters.Add("ListOfInts",concatenatedIds);

Ответ 6

Лучший способ справиться с этим - сохранить список в базе данных, чтобы вы могли написать запрос выбора для возврата значений в свой список. Вопрос в том, как вы можете это сделать, когда данные возникают у клиента? В большинстве случаев эти данные выбираются пользователем, по одной записи за раз. В этом случае вы можете использовать таблицу (подумайте: "корзина покупок" ), которая добавляет записи для значений по одному, так как пользователь их выбирает. Если это больше пакетного задания, вы можете использовать процесс BulkInsert для создания записей.