2012-07-16 28 views
14

Tôi có một câu lệnh SQL như sau:Tôi làm cách nào để cung cấp Danh sách <int> cho tham số SQL?

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

Làm thế nào tôi có thể cung cấp các dấu phẩy tách ra danh sách các ints, mà có thể là bất kỳ (hợp lý *) Số các giá trị

  • Bằng cách "hợp lý" trong trường hợp này tôi có nghĩa là giữa một và một vài chục.
+0

tại sao không được lưu trữ các giá trị trong một chuỗi được phân tách bằng dấu phẩy? –

+0

@Groo: Bạn nhận ra câu hỏi này đã hơn bốn tuổi, tôi hy vọng. –

+0

@ B.ClayShannon: hi, vâng, tôi chỉ đơn giản nhận thấy rằng một số câu hỏi tương tự về cơ bản là cùng một câu hỏi được liên kết vì vậy tôi đã đi qua tất cả chúng và thêm liên kết vào cái cũ nhất. Tôi không có bất cứ điều gì với một trong số này, tôi chỉ muốn làm một số dọn dẹp như tôi thường làm khi tôi tìm thấy một sợi chung. – Groo

Trả lời

0

CẬP NHẬT: Như Lasse chỉ ra bạn không thể đạt được những gì Clay đang cố gắng làm theo phương pháp dưới đây. Trong khi điều này không vượt qua trong một danh sách các số được phân tách bằng dấu phẩy, nó sẽ không thực thi như mong đợi. Rất tiếc, tôi không thể xóa điều này vì đó là câu trả lời được chấp nhận.


Hãy thử một cái gì đó như thế này:

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

Phương pháp String.Join mất tất cả các yếu tố trong một mảng và đặt ký tự quy định giữa họ.

+0

Tại sao điều này được chấp nhận làm câu trả lời? Bạn không thể thực sự làm theo cách này. –

+6

Vì câu trả lời đúng là: Không thể thực hiện theo cách này! Bạn không thể cung cấp một tham số duy nhất sẽ làm việc trong mệnh đề 'IN' với tham số chuỗi. Tham số có giá trị bảng có thể hoạt động, thông số chuỗi sẽ ** không ** hoạt động. Bây giờ, tôi hiểu rằng bạn đã trả lời câu hỏi đã được hỏi, nhưng quan điểm của tôi là bạn cần phải trả lời câu hỏi đã được ngụ ý: cách thực hiện công việc này. Trả lời: Nó không thể. –

+1

Được rồi, đủ công bằng. –

1

Sử dụng phương pháp Joinstring trên Mảng Ints. Bạn có thể đề cập đến comma như seperator

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

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

Sản lượng (giá trị trong concatenatedIds) sẽ 4,6,2. Bạn có thể sử dụng chuỗi như giá trị tham số cho khoản IN bạn

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

Trong khi điều này sẽ thêm một tham số tốt, nó sẽ không hoạt động với mệnh đề 'in (@ListOfInts)' trong SQL. Các tham số không hoạt động theo cách đó. Mong muốn suy nghĩ, tôi biết, nhưng không. –

3

Tôi nghĩ giải pháp duy nhất có thể là chuyển các giá trị được phân cách bằng dấu phẩy, mà bạn có thể chuyển đổi thành một bảng trong SQL bằng cách sử dụng hàm. Đây là chức năng Tôi đang sử dụng

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 

và bạn có thể sử dụng đoạn mã sau (ví dụ) để thực hiện các hoạt động:

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)) 

tôi lấy mã từ đây: http://www.geekzilla.co.uk/view5C09B52C-4600-4B66-9DD7-DCE840D64CBD.htm

Hy vọng nó giúp.

+0

Tôi quên nói rằng bạn phải sử dụng phương thức String.join để tổng hợp tất cả các giá trị và sau đó chuyển chúng thành các tham số cho mã SQL. –

11

Bạn không thể, bạn phải tạo một số hàm trợ giúp thay thế :ListOfInts bằng (ví dụ) :I0,:I1,:I2... và chuyển tham số bằng cách thêm từng mã một vào mã. Hàm bạn muốn được mô phỏng một cách duyên dáng bởi Dapper.Net trong its list support.

+0

Câu trả lời này là chính xác, trái ngược với câu trả lời được chấp nhận và câu trả lời 3 bình chọn khác. Tất nhiên bạn có thể sử dụng * một loạt các tham số, và tiêm các tham số đó, về cơ bản nhận được một câu lệnh SQL như 'trong đó id trong (@ id1, @ id2, @ id3, ...)'. Ngoài ra còn có [tham số giá trị bảng] (http://msdn.microsoft.com/en-us/library/bb675163 (v = vs.110) .aspx) bây giờ, nhưng tôi không biết liệu/làm thế nào chúng có thể được thừa hưởng để thực sự sử dụng 1 tham số để chỉ định danh sách các giá trị "IN" để đối sánh. –

1

Cách tốt nhất để xử lý việc này là giữ danh sách trong cơ sở dữ liệu, sao cho bạn có thể viết truy vấn chọn để trả về các giá trị trong danh sách của bạn. Câu hỏi đặt ra là, làm cách nào bạn có thể thực hiện điều này khi dữ liệu bắt nguồn từ ứng dụng khách? Hầu hết thời gian, dữ liệu này được người dùng chọn thủ công, một bản ghi tại một thời điểm. Trong trường hợp đó, bạn có thể sử dụng một bảng (suy nghĩ: "giỏ mua hàng") thêm các bản ghi cho các giá trị một tại một thời điểm, khi người dùng chọn chúng. Nếu đó là một công việc hàng loạt, bạn có thể muốn sử dụng một quy trình BulkInsert để tạo các bản ghi.

4

Bạn không biết bạn đang sử dụng cơ sở dữ liệu nào, nhưng nếu đó là SQL Server 2008+ bạn cũng có thể muốn xem xét Table Valued Parameters.

Ví dụ của bạn, độ phức tạp thêm có thể không đáng giá, nhưng chúng có thể hữu ích trong các trường hợp khác.

Các vấn đề liên quan