【问题标题】:How can I supply a List<int> to a SQL parameter? [duplicate]如何将 List<int> 提供给 SQL 参数? [复制]
【发布时间】:2012-07-15 12:47:12
【问题描述】:

我有如下 SQL 语句:

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

如何提供逗号分隔的整数列表,它可以是任何(合理*)数量的值

  • 在这种情况下,我所说的“合理”是指一到几十个。

【问题讨论】:

  • @B.ClayShannon:嗨,是的,我只是注意到几个类似的问题基本上是相同的链接问题,所以我浏览了所有问题并将链接添加到最旧的问题。这两个我都没有,我只是想像我通常在找到一个共同线程时那样做一些清理工作。

标签: c# sql winforms


【解决方案1】:

您没有说明您使用的是哪个数据库,但如果是 SQL Server 2008+,您可能还需要考虑Table Valued Parameters

对于您的示例,增加的复杂性可能不值得,但它们在其他场景中可能很有用。

【讨论】:

    【解决方案2】:

    处理此问题的最佳方法是将列表保存在数据库中,这样您就可以编写一个选择查询来返回列表中的值。问题是,当数据来自客户端时,你怎么能做到这一点?大多数情况下,这些数据是由用户亲自挑选的,一次一条记录。在这种情况下,您可以使用一个表格(想想:“购物车”),在用户选择它们时,一次添加一个值的记录。如果它更像是一个批处理作业,您可能需要使用 BulkInsert 进程来创建记录。

    【讨论】:

      【解决方案3】:

      在 Ints 数组上使用 stringJoin 方法。您可以提及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);
      

      【讨论】:

      • 虽然这会很好地添加一个参数,但它不适用于 SQL 中的 in (@ListOfInts) 子句。参数不是这样工作的。一厢情愿,我知道,但没有。
      • 这样不行
      【解决方案4】:

      您不能,您必须创建一些辅助函数,将:ListOfInts 替换为(例如):I0,:I1,:I2...,并通过在代码中一一添加来传递参数。 Dapper.Net in its list support 优雅地模拟了您想要的功能。

      【讨论】:

      • 这个答案是正确的,而不是接受的一个和其他 3-upvoted 一个。您当然可以使用 一堆 参数,然后注入这些参数,基本上得到像 where id in (@id1, @id2, @id3, ...) 这样的 SQL。现在还有Table-valued parameters,但我不知道是否/如何利用它们来实际使用1个参数来指定要匹配的“IN”值列表。
      【解决方案5】:

      我认为唯一可能的解决方案是传递逗号分隔的值,您可以使用函数将其转换为 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

      希望对你有帮助。

      【讨论】:

      • 我忘了说你必须使用 String.join 方法来聚合所有值,然后将它们作为参数传递给 SQL 代码。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-12
      • 2020-02-27
      • 2014-04-06
      • 1970-01-01
      • 1970-01-01
      • 2015-03-09
      相关资源
      最近更新 更多