2012-07-16 49 views
14

我有类似下面的SQL语句:如何向SQL参数提供列表<int>?

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

我如何提供整数的逗号分隔的列表,这可能是任何(合理*)数值的

  • 通过“合理”在这种情况下,我的意思是介于一个和几十个之间。
+0

为什么不将值存储在用逗号分隔的字符串中? – 2012-07-16 16:16:44

+0

@格鲁:你确实意识到这个问题已经过了四岁了,我希望。 – 2016-09-07 15:53:45

+0

@ B.ClayShannon:嗨,是的,我只是注意到几个类似的问题基本上是相同的链接问题,所以我经历了所有这些问题,并将链接添加到最旧的链接。我没有任何这些东西,我只是想像我通常那样做一些清理工作,当我找到一个共同的线程。 – Groo 2016-09-08 07:24:10

回答

0

UPDATE:作为拉塞指出,你不能达到什么克莱尝试使用下面的方法做。虽然这确实通过了昏迷分离的数字列表,但它不会按预期执行。不幸的是我不能删除这个,因为这是被接受的答案。


尝试是这样的:

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

String.Join方法通吃数组中的元素,并将它们之间的指定字符。

+0

为什么这被接受为答案?你不能这样做。 – 2014-01-03 20:20:07

+6

因为正确的答案是:它不能这样做!你不能提供一个单个的参数,这个参数在一个带有字符串参数的'IN'子句中起作用。一个表值参数可能工作,一个字符串参数将**不工作。现在,我明白你回答了被问到的问题,但我的观点是你需要回答暗示的问题:如何使这项工作。答:不可以。 – 2014-01-03 23:12:39

+1

好吧,够公平的。 – 2014-01-03 23:17:50

1

在Ints阵列上使用方法string。你可以提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); 
+5

虽然这会添加一个参数,但它不适用于SQL中的in(@ListOfInts)子句。参数不能这样工作。我知道,我有充分的想法,但没有。 – 2014-01-03 20:27:52

3

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

希望它帮助。

+0

我忘了说,你必须使用String.join方法来聚合所有的值,然后将它们作为参数传递给SQL代码。 – 2012-07-16 16:14:59

11

你不能,你必须创建一些辅助函数,用:ListOfInts替代(例如):I0,:I1,:I2...,并通过在代码中逐个添加参数来传递参数。您想要的功能在its list support中由Dapper.Net正常模拟。

+0

这个答案是正确的,而不是接受的和其他3-upvoted之一。你当然可以使用*一堆参数,然后注入这些参数,基本上得到一个像'@id1,@ id2,@ id3,...'这样的'where id'的SQL。现在还有[Table-valued parameters](http://msdn.microsoft.com/en-us/library/bb675163(v = vs.110).aspx),但我不知道他们是否可以/如何被用来实际使用1个参数来指定匹配的“IN”值列表。 – 2014-01-03 20:26:23

1

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

4

你没有说明你正在使用哪个数据库,但是如果它是SQL Server 2008+,你可能还想考虑Table Valued Parameters

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