web-dev-qa-db-ja.com

SQLパラメータにList <int>を提供するにはどうすればよいですか?

次のようなSQLステートメントがあります。

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

どのように(合理的な*)値の数でもかまわないintのコンマ区切りリストを提供するにはどうすればよいですか?

  • この場合の「合理的」とは、1から数十の間を意味します。
18
B. Clay Shannon

[〜#〜] update [〜#〜]:ラッセが指摘しているように、クレイが以下の方法を使用して実行しようとしていることを達成することはできません。これは数値のコマ区切りのリストを渡しますが、期待どおりに実行されません。残念ながら、これは受け入れられた回答なので削除できません。


次のようなものを試してください:

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

String.Join メソッドは、配列内のすべての要素を取り、それらの間に指定された文字を配置します。

0
Abe Miessler

できません。:ListOfIntsを(たとえば):I0,:I1,:I2...に置き換えるヘルパー関数を作成し、コードに1つずつ追加してパラメーターを渡す必要があります。必要な関数は そのリストのサポートDapper.Net によって適切にエミュレートされます。

12
Felice Pollano

考えられる唯一の解決策は、関数を使用して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
Umar Jamil

使用しているデータベースは明記していませんが、SQL Server 2008+の場合は、 Table Valued Parameters を検討することもできます。

あなたの例では、追加された複雑さは価値がないかもしれませんが、それらは他のシナリオで役立ちます。

4
James Simpson

Intの配列でJoinstringメソッドを使用します。 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);
1
Shyju

これを処理する最良の方法は、リストをデータベースに保持することです。これにより、選択クエリを記述してリストの値を返すことができます。問題は、データがクライアントで発信されたときに、これをどのように行うことができるかです。ほとんどの場合、このデータはユーザーが1つずつレコードを選択します。その場合、ユーザーが値を選択するときに、値のレコードを1つずつ追加するテーブル(「ショッピングカート」など)を使用できます。バッチジョブの場合は、BulkInsertプロセスを使用してレコードを作成できます。

1
Joel Coehoorn