2012-07-16 25 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

對於您的示例,增加的複雜性可能不值得,但它們在其他情況下可能很有用。

相關問題